JavaRush /Java блог /Random UA /Складальник сміття в Java (Garbage Collector)
Diana
41 рівень

Складальник сміття в Java (Garbage Collector)

Стаття з групи Random UA

Лінія поведінки збирача сміття (утилізатора пам'яті)

Java-програмісту не потрібно стежити за розподілом пам'яті, оскільки збирач сміття керує пам'яттю автоматично. Складальник сміття (Garbage Collector) запускається віртуальною машиною Java (JVM). Складальник сміття — це низькопріоритетний процес, який періодично запускається і звільняє пам'ять, використану об'єктами, які більше не потрібні. Різні JVM мають відмінні один від одного алгоритми збору сміття. Існує кілька використовуваних алгоритмів, наприклад: алгоритм підрахунку посилань або алгоритми розмітки та очищення.Складання сміття - 1

Запуск збирача сміття в Java

JVM зазвичай запускає збирач сміття за низького рівня вільної пам'яті. Але робота збирача сміття не гарантує, що завжди залишатиметься достатньо вільної пам'яті. Якщо пам'яті недостатньо навіть після відновлення, JVM генерує виключення OutOfMemoryError. Зверніть увагу, що перед генеруванням виключення JVM обов'язково запускає збирач сміття щонайменше 1 раз. Ви можете запитити запуск збирача сміття Java, але ви не можете примусово задавати цю дію.

Запит запуску збирача сміття

Для запиту ви можете викликати один із таких методів:
System.gc()
Runtime.getRuntime().gc()

Придатність для запуску збирача сміття

Об'єкт підлягає утилізації, коли вона недоступна живому потоку. Об'єкт може підлягати утилізації в різних випадках:
  • Якщо змінна типу посилання, яка посилається на об'єкт, встановлена ​​в положення "0", об'єкт підлягає утилізації, у тому випадку, якщо на нього немає інших посилань.
  • Якщо змінна типу посилання, яка посилається на об'єкт, створена для посилання на інший об'єкт, об'єкт підлягає утилізації, якщо на нього немає інших посилань.
  • Об'єкти, створені локально в методі, підлягають утилізації, коли метод завершує роботу, якщо вони не експортуються з цього методу (тобто, повертаються або генеруються як виняток).
  • Об'єкти, які посилаються один на одного, можуть підлягати утилізації, якщо жоден із них не доступний живому потоку.
Розглянемо приклад:
public class TestGC
  {
    public static void main(String [] args)
    {
      Object o1 = new Integer(3);               // Line 1
      Object o2 = new String("Tutorial");       // Line 2
      o1 = o2;                                  // Line 3
      o2 = null;                                // Line 4
      // Rest of the code here
    }
  }
У цьому прикладі об'єкт Integer(цілочисленний), який спочатку посилається покажчик o1 може піддаватися утилізації після рядка 3, так як o1 тепер посилається на об'єкт String(рядковий). Незважаючи на те, що o2 створений для посилання на нуль, об'єкт String(рядковий) не підлягає утилізації, оскільки o1 посилається на нього.

Фіналізація

Java-технологія дозволяє використовувати метод finalize()(фіналізувати), щоб зробити необхідне очищення перед тим, як збирач сміття витягує об'єкт із пам'яті. Цей метод викликається для об'єкта збирачем сміття, коли збирач сміття обчислює, що посилань до об'єкта більше немає. Це описано в класі Object, отже, це успадковується всіма класами. Підклас скасовує метод finalize(), щоб звільнитися від системних ресурсів або ще однієї очищення:
protected void finalize() throws Throwable
Якщо незареєстрований виняток генерується методом finalize(), виняток ігнорується і фіналізація цього об'єкта припиняється. Метод finalize()буде активовано лише один раз за час існування об'єкта. Можливе використання методу finalize()будь-якого об'єкта, щоб захистити його від утилізації. Але в цьому випадку збирач сміття вже не активує finalize()для цього об'єкта. Метод finalize()завжди буде активізований один раз перед тим, як об'єкт буде видалений збирачем сміття. Однак, можливо, що метод finalize()не буде активізовано для даного об'єкта за весь час його існування, оскільки він може не підлягати утилізації.

Резюме

У цьому розділі ми розглянули процес складання сміття, який відноситься до техніки управління пам'яттю Java. Складання сміття не може бути задане примусово. Ми познайомабося з різними способами звернення об'єктів у утилізації, що підлягають, і дізналися, що метод finalize()активізується перед тим, як об'єкт витягується збирачем сміття.

Вправа

Запитання: Скільки об'єктів підлягатимуть утилізації після рядка 7?
public class TutorialGC
  {
    public static void main(String [] args)
    {
      Object a = new Integer(100);  // Line1
      Object b = new Long(100);     // Line2
      Object c = new String("100"); // Line3
      a = null;                     // Line4
      a = c;                        // Line5
      c = b;                        // Line6
      b = a;                        // Line7
      // Rest of the code here
    }
  }
Варіанти відповіді: A. 0 B. 1 C. 2 D. 3 E. Код неможливо скомпілювати Правильний варіант: B Пояснення: з трьох об'єктів, створених у рядках 1, 2 та 3, тільки об'єкт Integerпідлягає утилізації в кінці рядка 7. Змінна посилання, a, яка спочатку посилалася на об'єкт Integer, посилається на об'єкт Stringу рядку 5. Таким чином, Integerоб'єкт підлягає утилізації після рядка 5, оскільки немає змінних, які посилаються на нього. Змінні bта cпосилаються на об'єкти Stringта Longоб'єкти у рядках 6 та 7, тому вони не підлягають утилізації.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ