Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 12807|Відповідь: 0

[JavaSE] Отримайте глибоке розуміння механізму збору сміття в Java

[Копіювати посилання]
Опубліковано 04.12.2017 20:26:51 | | |
1. Значення механізму переробки сміття  
Важливою особливістю мови Java є впровадження механізму збору сміття, який вирішує найскладнішу проблему управління пам'яттю для програмістів C++, тож програмістам Java більше не потрібно враховувати управління пам'яттю при написанні програм. Через механізм збору сміття об'єкти в Java більше не мають поняття «обсягу», лише посилання на об'єкт має «область видимості».Збір сміття може ефективно запобігати витоку пам'яті та ефективно використовувати пам'ять у режимі простою.

ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
2. Алгоритми у механізмах збору сміття  
Специфікація мови Java прямо не вказує, який саме алгоритм збору сміття використовувати в JVM, але будь-який алгоритм збору сміття зазвичай повинен виконувати дві основні речі: (1) знаходити непотрібні інформаційні об'єкти; (2) Відновити простір пам'яті, зайнятий непотрібними об'єктами, щоб програма могла знову використовувати цей простір.
1. Референсний колектор для підрахунку
1.1 Аналіз алгоритмів

Підрахунок референсів — це рання стратегія у сміттєзбирачів. У цьому підході існує кількість посилань для кожного екземпляра об'єкта в купі. Коли створюється об'єкт і екземпляр об'єкта призначається змінної, кількість змінних встановлюється як 1. Коли будь-яка інша змінна призначається як посилання на цей об'єкт, підрахунок додається на 1 (a = b, тоді лічильник екземпляра об'єкта, на який посилається b, дорівнює +1), але коли посилання на екземпляр об'єкта перевищує свій житловий час або встановлюється на нове значення, лічильник референтного екземпляра об'єкта віднімається на 1. Будь-який екземпляр об'єкта з лічильником 0 може бути зібраний як сміття. Коли екземпляр об'єкта — це сміття, лічильник посилань будь-якого екземпляра об'єкта, на який він посилається, дорівнює мінус 1.
1.2 Переваги та недоліки
Заслуга:

Колектор референсної кількості може бути виконаний дуже швидко, інтегрований у запуск програми. Це вигідно для реальних часових середовищ, де програми не потрібно довго переривати.
Недолік:

Кругові посилання не можуть бути виявлені. *Якщо батьківський об'єкт має посилання на дочірній об'єкт, дочірній об'єкт, у свою чергу, посилається на батьківський об'єкт. Таким чином, їхня кількість цитувань ніколи не може бути нульовою.
1.3 Алгоритм підрахунку посилань не може розв'язати задачу кругового посилання, наприклад:
/** * Java学习交流QQ群:589809992 我们一起学Java! */public class Main {    public static void main(String[] args) {        MyObject object1 = new MyObject();        MyObject object2 = new MyObject();        object1.object = object2;        object2.object = object1;        object1 = null;        object2 = null;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  
Останні два речення присвоюють об'єкт1 і об'єкт2 до null, що означає, що об'єкти, на які вказують object1 і object2, більше неможливо отримати доступ, але оскільки вони посилаються один на одного, їхні лічильники посилань не дорівнюють 0, тому збирач сміття ніколи не буде їх переробляти.
2. Алгоритм трасування колектора або позначки та сканування
2.1 Алгоритм кореневого пошуку


Алгоритм пошуку кореня вводиться з теорії графів у дискретній математиці: програма розглядає всі референсні відношення як граф, починаючи з вузла GC ROOT, шукаючи відповідний референтний вузол, після знаходження цього вузла, продовжуючи шукати референсний вузол цього вузла, коли всі референсні вузли будуть пошука, решта вершин вважаються непосиланими, тобто марними вузлами.
java, яку можна використовувати як корень GC
1. Об'єкти, на які посилаються у стеку віртуальної машини (таблиця локальних змінних)
2. Об'єкт, на який посилається статичний атрибут у області методу
3. Об'єкт, на який посилається константа в області методу
4. Посилані об'єкти в локальному стеку методів (рідні об'єкти)
2.2 Схематична діаграма алгоритму трасування

2.3 Аналіз алгоритму очищення маркерів

Алгоритм очищення тегів сканує кореневу колекцію, позначає об'єкти, що залишилися, а потім сканує весь простір у пошуках непозначених об'єктів для повторного використання, як показано на рисунку вище. Алгоритм очищення тегів не потребує переміщення об'єктів і обробляє лише ті, що не вижили, що є надзвичайно ефективним, коли є багато об'єктів, але оскільки алгоритм очищення тегів безпосередньо перепрацьовує неживі об'єкти, це спричиняє фрагментацію пам'яті.
3. Алгоритм компактування або алгоритм завершення міток


Алгоритм tag-finish використовує той самий метод, що й алгоритм очищення тегів, для маркування об'єктів, але при очищенні він відрізняється — після повернення простору, зайнятого неживими об'єктами, всі об'єкти переміщуються у вільний простір на лівому кінці і оновлюється відповідний вказівник. Алгоритм закінчення тегів базується на алгоритмі очищення тегів і переміщує об'єкти, тому він дорожчий, але вирішує проблему фрагментації пам'яті. У реалізації колекторів на основі алгоритму компактування зазвичай додаються таблиці handles і handles.
4. Алгоритм копіювання (компактний колектор)


Алгоритм запропонований для подолання накладних витрат ручки та вирішення проблеми збору сміття з купи. Коли об'єкт заповнений, збірка сміття на основі алгоритму копіювання сканує активний об'єкт із кореневої множини і копіює кожен активний об'єкт на вільну грань (щоб між пам'яттю, зайнятою активним об'єктом, не було вільних отворів), так що вільна поверхня стає гранню об'єкта, оригінальна грань об'єкта — вільною, а програма виділяє пам'ять у нову грань об'єкта. Типовий збір сміття, заснований на алгоритмі копінгу, — це алгоритм стопи і копіювання, який ділить купу на грані об'єктів і грані вільної області, і програма призупиняє виконання під час перемикання між гранями об'єктів і гранями вільної області.
5. Колекціонер поколінь


Поколіннєва стратегія переробки сміття базується на тому, щоЖиттєвий цикл різних об'єктів різний。 Тому об'єкти з різним життєвим циклом можуть використовувати різні алгоритми переробки для підвищення ефективності переробки.
Молоде покоління
1. Усі новостворені об'єкти спочатку розміщуються до молодшого покоління. Мета молодшого покоління — якомога швидше збирати ці предмети з коротким життєвим циклом.

2. Пам'ять нового покоління поділена на один регіон Едем і дві зони виживання (виживший0, виживший1) за співвідношенням 8:1:1. Одна зона Едему, дві зони виживання (загалом). Більшість об'єктів з'являються в районі Едему. Коли область Survivor0 також заповнена, область Eden і Survivor 0 копіюються в іншу область Survivor1, потім Eden і Survivor0 спорожнюються, потім зона Survivor0 порожняє, а потім Survivor0 і Survivor1 обмінюються. Тобто залишати зону Survivor1 порожньою і так далі.

3. Коли області Survivor 1 недостатньо для зберігання збережених об'єктів Eden і Survivor0, ті предмети зберігаються безпосередньо в стару епоху. Якщо старість також повна, це спровокує повний GC, тобто нове покоління, і старе покоління буде перероблене

4. GC нового покоління також називають Minor GC, і частота MinorGC досить висока (вона не обов'язково активується, коли район Едем заповнений)
Старе покоління

1. Об'єкти, які залишилися живими після переробки азотного сміття у молодшому поколінні, будуть віднесені до старшого покоління. Отже, можна вважати, що старе покоління зберігається в деяких об'єктах із тривалим життєвим циклом.

2. Пам'ять також значно більша, ніж у нового покоління (приблизне співвідношення 1:2), коли пам'ять старого віку заповнена, активується Major GC, тобто повний GC, частота повного GC відносно низька, час виживання об'єкта старості відносно довгий, а позначка виживання виживання висока.
Постійне покоління
Використовується для зберігання статичних файлів, таких як класи Java, методи тощо. Постійні генерації не мають суттєвого впливу на збір сміття, але деякі додатки можуть динамічно генерувати або викликати деякі класи, такі як Hibernate тощо, і в цьому випадку потрібно встановити відносно великий простір постійних генерацій для зберігання цих нових класів під час виконання процесу.
3. GC (Сміттєзбір)Колекціонери, які використовують колекціонери нового покоління: Serial, PraNew, Parallel Scavenge
Колекціонери, які використовують колекціонери старості: Serial Old, Parallel Old, CMS

Серійний колектор (алгоритм реплікації)
Нове покоління однониточкових колекторів, маркування та очищення мають одну нитку, з перевагою простоти та ефективності.
Послідовний старий колектор (алгоритм оздоблення етикеток)
Старовинний однонитковий колекціонер, старовинна версія серійного колекціонера.
ParNew колектор (алгоритм стоп-копіювання)
Нове покоління колектора можна вважати багатопотоковою версією Serial Collector, яка має кращу продуктивність, ніж Serial у багатоядерному середовищі процесора.
Паралельний збирач скавенжу (алгоритм стоп-копіювання)
Паралельні колектори для високої пропускної здатності та ефективного використання процесора. Пропускна здатність зазвичай становить 99%, а пропускна здатність = час потоку користувача / (час потоку користувача + час потоку GC). Він підходить для ситуацій, таких як фонові застосування, які не потребують високої взаємодії відповідно.
Паралельний старий колектор (алгоритм стоп-копіювання)
Старіша версія колектора Parallel Scavenge — паралельний колектор, з пріоритетом пропускної здатності
Колектор CMS (Concurrent Mark Sweep) (Алгоритм очищення маркування)
Висока паралельність, низька пауза, прагнення до найкоротшого часу паузи відновлення GC, високого завантаження процесора, швидкого відгуку, короткого часу паузи та багатоядерних процесорів з високим часом відгуку
4. Механізм впровадження GCОскільки об'єкт оброблявся в різних поколіннях, площа та час збору сміття також відрізняються. Існує два типи GC: Scavenge GC і Full GC.
Scavenge GC
Зазвичай, коли генерується новий об'єкт і він не подається на місце в Едемі, активується GC Scavenge GC, який знищує територію Eden, очищає об'єкти, що не вижили, і переміщує виживші об'єкти до зони Survivor. Потім розібратися з двома зонами Survivor. ГК таким чином проводиться в районі Едем молодого покоління і не впливає на старше покоління. Оскільки більшість об'єктів починаються з району Едем, а територія Едему розподіляється незначно, генеральний комплекс району Едем проводиться часто. Тому загалом необхідно використовувати швидкі та ефективні алгоритми, щоб якнайшвидше зробити Едем вільним.
Повний GC
Організуйте всю купу, включно з молодими, постійними та перманними. Повний GC повільніший за Scavenge GC, оскільки вимагає переробки всієї купи, тому кількість повних GC слід зменшити настільки, наскільки це можливо. Велика частина процесу налаштування JVM — це налаштування FullGC. Повний ГК може бути спричинений такими причинами:
1. Постійний контракт пишеться повністю
2. Перм пишеться повністю  
3. System.gc() відображається як виклик  
4. Стратегія розподілу доменів у Heap динамічно змінюється після останнього GC
5. Java з GC також матиме проблеми з витоком пам'яті1. Використання класів статичних колекцій, таких як HashMap, Vector тощо, є найбільш схильним до витоку пам'яті, і життєвий цикл цих статичних змінних такий самий, як у застосунку, і всі об'єкти не можуть бути звільнені, оскільки вони завжди будуть застосовуватися Vector та іншими.
Статичний вектор v = новий вектор(); для (int i = 1; i<100; i++) { Об'єкт o = новий Об'єкт();     v.add(o);     o = нуль; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  
У цьому прикладі є посилання v для векторного об'єкта та посилання o для об'єкта Object у стеку коду. У циклі For ми постійно генеруємо нові об'єкти, потім додаємо їх до об'єкта Vector і потім нейтралізуємо посилання на o. Питання в тому, коли посилання на o анульоване, якщо виникає GC, чи може створений нами об'єкт Object бути перероблений GC? Відповідь — ні. Тому що, коли GC відстежує посилання в стеку коду, він знаходить v посилання, і якщо продовжити трасування вниз, то знайдете посилання на об'єкти об'єктів у просторі пам'яті, на який вказують v посилання. Це означає, що навіть після того, як посилання на o було спорожнено, все ще є інші посилання на об'єкт Object, до яких можна отримати доступ, тому GC не може їх звільнити. Якщо після цього циклу об'єкт Object не впливає на програму, то припускаємо, що програма Java має витік пам'яті.
2. Різні з'єднання, бази даних, мережеві з'єднання, виводні з'єднання тощо не відображають дзвінок близький до закриття і не переробляються GC, що призводить до витоку пам'яті.
3. Використання слухачів також може спричинити витік пам'яті, якщо слухач не видаляється під час випуску об'єкта.




Попередній:Новачки грають у чорні технології в CSS
Наступний:Остерігайтеся вірусу Wanke Cloud Snap Software Trojan!
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com