Прибирання сміття
Прибирання сміття
Прибирання сміття
Лінія поведінки збирача сміття (утилізатора пам'яті)
Java-програміста не потрібно стежити за розподілом пам'яті, так як збирач сміття управляє пам'яттю автоматично. Складальник сміття запускається віртуальною машиною Java (JVM). Складальник сміття - це фоновий процес, який запускається періодично і звільняє пам'ять, використану об'єктами, які більше не потрібні.
Запуск збирача сміття
JVM зазвичай запускає збирач сміття при низькому рівні вільної пам'яті. Але робота збирача сміття не гарантує, що завжди залишатиметься достатньо вільного місця.
Якщо пам'яті недостатньо навіть після відновлення, JVM генерує виняток OutOfMemoryError. Зверніть увагу, що перед генеруванням виключення JVM обов'язково запускає збирач сміття як мінімум 1 раз.
Ви можете запитати запуск збирача сміття, але ви не можете примусово здавати цю дію.
Запит запуску збирача сміття
Для запиту ви можете викликати один з наступних методів:
Придатність для запуску збирача сміття
Об'єкт підлягає утилізації, коли він недоступний живому потоку.
Об'єкт може підлягати утилізації в різних випадках:
- Якщо змінна посилального типу, яка посилається на об'єкт, встановлена в положення «0», об'єкт підлягає утилізації, в тому випадку, якщо на нього немає інших посилань.
- Якщо змінна посилального типу, яка посилається на об'єкт, створена для посилання на інший об'єкт, об'єкт підлягає утилізації, в тому випадку, якщо на нього немає інших посилань.
- Об'єкти, створені локально в методі, підлягають утилізації, коли метод завершує роботу, якщо тільки вони не експортуються з цього методу (тобто, повертаються або генеруються як виняток).
- Об'єкти, які посилаються один на одного, можуть підлягати утилізації, якщо жоден з них не доступний живому потоку.
Розглянемо приклад:
У цьому прикладі об'єкт Integer (цілочисельний), на який спочатку посилається покажчик o1 може піддаватися утилізації після рядка 3, так як o1 тепер посилається на об'єкт String (строковий). Незважаючи на те, що o2 створений для посилання до нуля, об'єкт String (строковий) не можна поводитися, так як o1 посилається на нього.
Фіналізація
Java-технологія дозволяє використовувати метод finalize () (фіналізувати), щоб зробити необхідну очистку перед тим, як збирач сміття витягує об'єкт з пам'яті. Цей метод викликається для об'єкта складальником сміття, коли збирач сміття обчислює, що посилань до об'єкта більше немає. Це описано в класі Object, а значить, це успадковується всіма класами. Підклас скасовує метод finalize (), щоб звільнитися від системних ресурсів або для ще однієї очищення:
Якщо незареєстровану виняток генерується методом finalize (), то виключення ігнорується і фіналізація цього об'єкта припиняється.
Метод finalize () буде активізований тільки один раз за час існування об'єкта.
Можливе використання методу finalize () будь-якого об'єкта, щоб захистити його від утилізації. Але в цьому випадку збирач сміття вже не активує finalize () для цього об'єкта.
Метод finalize () завжди буде активізований один раз перед тим, як об'єкт буде видалений складальником сміття. Однак, можливо, що метод finalize () не активізований для даного об'єкта за весь час його існування, так як він може не підлягати утилізації.
У цьому розділі ми розглянули процес складання сміття, який відноситься до техніки управління пам'яттю мови Java. Прибирання сміття не може бути задана примусово. Ми познайомилися з різними способами звернення об'єктів в підлягають утилізації та дізналися, що метод finalize () активізується перед тим, як об'єкт витягується складальником сміття.
Вправа
Скільки об'єктів підлягатимуть утилізації після рядка 7?
Варіанти відповіді:
A. 0
B. 1
C. 2
D. 3
E. Код неможливо скомпілювати
Правильний варіант:
пояснення:
З трьох об'єктів, створених в рядках 1, 2 і 3, тільки об'єкт Integer можна поводитися, наприкінці рядка 7. Мінлива посилання, a, яка спочатку посилалася на об'єкт Integer, посилається на об'єкт String в рядку 5. Таким чином, Integer oб'ект підлягає утилізації після рядка 5, так як немає змінних, які посилаються на нього. Змінні b і c посилаються на об'єкти String і Long об'єкти в рядках 6 та 7, тому вони не підлягають утилізації.
У статті згадується така дивна штука, як фіналізатор. Я завжди думав, що це щось на зразок деструктора (ну тобто він і є), але раз про нього написали, варто було б розібратися. У мене не багатий досвід знання Java, але я так зрозумів, що це злісний милицю. У загальному ось пара посилань які мені сподобалися (може хтось ще чого небудь порадить).
habrahabr.ru/post/183344/
ru.wikipedia.org/wiki/.0%A4.0%B8.0%BD.0%B0.0%BB.0%B8.0%B7.0%B0.1%82.0%BE.1%80
Треба було кілька питань в кінці, для закріплення. Я відразу вгадав, і відразу захотілося себе ще перевірити!
Для новачка про finalize () незрозуміло (Треба почитати де-небудь ще
Ем ... А чому в поясненні об'єкту підлягає утилізації після строкі5, якщо після 4 на нього ууже ніхто не посилається?
Якщо код написали по іншому: b = a, потім а = null, і далі a = c ... то об'єкт Integer (100) ще існував після видалення посилання в змінної «а = null», Integer (100) перебував би в зміною «b = a ». Вище набраному випадку об'єкт втрачається після а = null
Не зовсім розумію, чому відповідь 1? Поясніть будь ласка.
Ось моя логіка:
1. На Integer після 4 рядки а вже не посилається. (Integer потрібно знищити)
2. Після а присвоюється с, яка на сходинці 6 посилається вже на b. (Виходить, що на String змінна з вже не посилається).
3. Потім b посилається на а, і виходить що а = а! (На long змінна b вже не посилається).
Де помилка? Не розумію чому виходить відповідь, що знищується тільки Integer.