Рубрики

Сборка мусора на Java

Вступление

  • В C / C ++ программист отвечает как за создание, так и за уничтожение объектов. Обычно программист пренебрегает уничтожением ненужных объектов. Из-за этой небрежности в определенный момент для создания новых объектов может быть недоступно достаточное количество памяти, и вся программа будет аварийно завершать работу, вызывая OutOfMemoryErrors .
  • Но в Java программисту не нужно заботиться обо всех тех объектах, которые больше не используются. Сборщик мусора уничтожает эти объекты.
  • Сборщик мусора — лучший пример потока Daemon, поскольку он всегда работает в фоновом режиме.
  • Основная цель сборщика мусора — освободить кучу памяти, уничтожив недоступные объекты .

Важные условия:

  1. Недоступные объекты: объект считается недоступным, если он не содержит ссылок на него. Также обратите внимание, что объекты, которые являются частью острова изоляции , также недоступны.
    Integer i = new Integer(4);
    // the new Integer object is reachable  via the reference in 'i' 
    i = null;
    // the Integer object is no longer reachable. 
    

  2. Право на сборку мусора: говорят, что объект имеет право на GC (сборку мусора), если он недоступен. На изображении выше, после того как я = ноль; Целочисленный объект 4 в области кучи подходит для сборки мусора.

Способы сделать объект пригодным для GC

  • Хотя программист не несет ответственности за уничтожение бесполезных объектов, но настоятельно рекомендуется сделать объект недоступным (таким образом, пригодным для GC), если он больше не требуется.
  • Как правило, существует четыре различных способа сделать объект пригодным для сборки мусора.
      1. Обнулить ссылочную переменную
      2. Переназначение ссылочной переменной
      3. Объект создан внутри метода
      4. Остров изоляции

    Все вышеперечисленные способы с примерами обсуждаются в отдельной статье: Как сделать объект пригодным для сборки мусора

    Способы запроса JVM для запуска сборщика мусора

    • После того, как мы сделали объект пригодным для сбора мусора, он не может немедленно уничтожиться сборщиком мусора. Всякий раз, когда JVM запускает программу Garbage Collector, будет уничтожен только объект. Но когда JVM запускает сборщик мусора, мы не можем ожидать.
    • Мы также можем попросить JVM запустить сборщик мусора. Есть два способа сделать это:
        1. Использование метода System.gc () : системный класс содержит статический метод gc () для запроса JVM на запуск сборщика мусора.
        2. Использование метода Runtime.getRuntime (). Gc () : класс времени выполнения позволяет приложению взаимодействовать с JVM, в которой выполняется приложение. Следовательно, используя его метод gc (), мы можем запросить JVM запустить сборщик мусора.
        3. // Java-программа для демонстрации запроса
          // JVM для запуска сборщика мусора

          public class Test

          {

              public static void main(String[] args) throws InterruptedException

              {

                  Test t1 = new Test();

                  Test t2 = new Test();

                    

                  // Обнуляем ссылочную переменную

                  t1 = null;

                    

                  // запрашиваем JVM для запуска сборщика мусора

                  System.gc();

                    

                  // Обнуляем ссылочную переменную

                  t2 = null;

                    

                  // запрашиваем JVM для запуска сборщика мусора

                  Runtime.getRuntime().gc();

                

              }

                

              @Override

              // метод finalize вызывается для объекта один раз

              // перед сборкой мусора

              protected void finalize() throws Throwable

              {

                  System.out.println("Garbage collector called");

                  System.out.println("Object garbage collected : " + this);

              }

          }

          Выход:

          Garbage collector called
          Object garbage collected : Test@46d08f12
          Garbage collector called
          Object garbage collected : Test@481779b8
          

        Замечания :

        1. Нет никаких гарантий, что любой из двух вышеуказанных методов обязательно запустит сборщик мусора.
        2. Вызов System.gc () фактически эквивалентен вызову: Runtime.getRuntime (). Gc ()

      завершение

      • Непосредственно перед уничтожением объекта сборщик мусора вызывает метод finalize () для объекта для выполнения действий по очистке. После завершения метода finalize () сборщик мусора уничтожает этот объект.
      • Метод finalize () присутствует в классе Object со следующим прототипом.
        protected void finalize() throws Throwable
        

        На основании нашего требования мы можем переопределить метод finalize () для выполнения наших действий по очистке, таких как закрытие соединения с базой данных.

      • Замечания :

      1. Метод finalize () вызывается сборщиком мусора, а не JVM . Хотя Сборщик мусора является одним из модулей JVM.
      2. Метод класса объекта finalize () имеет пустую реализацию, поэтому рекомендуется переопределить метод finalize () для удаления системных ресурсов или другой очистки.
      3. Метод finalize () никогда не вызывается более одного раза для любого данного объекта.
      4. Если с помощью метода finalize () генерируется неперехваченное исключение, оно игнорируется, и завершение этого объекта завершается.

      Примеры методов finalize () см. В разделе « Вывод программ Java» | Набор 10 (Сборка мусора)

      Давайте возьмем реальный пример, где мы используем концепцию сборщика мусора.

      Предположим, вы идете на стажировку в GeeksForGeeks, и вам предложили написать программу для подсчета количества сотрудников, работающих в компании (исключая стажеров). Чтобы создать эту программу, вы должны использовать концепцию сборщика мусора.
      Это реальное задание, которое вам дали в компании: —

      В. Напишите программу для создания класса с именем Employee, имеющего следующие члены данных.
      1. Идентификатор для хранения уникального идентификатора, присвоенного каждому сотруднику.
      2. Имя работника.
      3. возраст работника.

      Также предоставьте следующие методы:

      1. Параметризованный конструктор для инициализации имени и возраста. Идентификатор должен быть инициализирован в этом конструкторе.
      2. Метод show () для отображения идентификатора, имени и возраста.
      3. Метод showNextId () для отображения идентификатора следующего сотрудника.

      Теперь любой новичок, который не имеет знаний о сборщике мусора, будет кодировать так:

      // Программа для подсчета числа
      // сотрудников работающих
      // в компании

        

      class Employee

      {

          private int ID;

          private String name;

          private int age;

          private static int nextId=1;

          // это сделано статическим, потому что это

          // это общее для всех и

          // общий для всех объектов

          public Employee(String name,int age)

          {

              this.name = name;

              this.age = age;

              this.ID = nextId++;

          }

          public void show()

          {

              System.out.println

              ("Id="+ID+"\nName="+name+"\nAge="+age);

          }

          public void showNextId()

          {

              System.out.println

              ("Next employee id will be="+nextId);

          }

      }

      class UseEmployee

      {

          public static void main(String []args)

          {

              Employee E=new Employee("GFG1",56);

              Employee F=new Employee("GFG2",45); 

              Employee G=new Employee("GFG3",25);

              E.show();

              F.show();

              G.show();

              E.showNextId();

              F.showNextId();

              G.showNextId();

                    

                  { // Это субблок для хранения

                  // все эти интерны.

                  Employee X=new Employee("GFG4",23);     

                  Employee Y=new Employee("GFG5",21);

                  X.show();

                  Y.show();

                  X.showNextId();

                  Y.showNextId();

              }

              // После противостояния этой скобке X и Y

              // будет удален. Поэтому

              // теперь он должен показывать nextId как 4.

              E.showNextId();// Вывод этой строки

              // должно быть 4, но это даст 6 как вывод.

          }

      }

      Выход:

      Id=1
      Name=GFG1
      Age=56
      Id=2
      Name=GFG2
      Age=45
      Id=3
      Name=GFG3
      Age=25
      Next employee id will be=4
      Next employee id will be=4
      Next employee id will be=4
      Id=4
      Name=GFG4
      Age=23
      Id=5
      Name=GFG5
      Age=21
      Next employee id will be=6
      Next employee id will be=6
      Next employee id will be=6
      

      Теперь, чтобы получить правильный вывод:
      Теперь сборщик мусора (gc) увидит 2 свободных объекта. Теперь, чтобы уменьшить значение nextId, gc (сборщик мусора) будет вызывать метод finalize () только тогда, когда мы, программисты, переопределим его в нашем классе. И, как упоминалось ранее, мы должны запросить gc (сборщик мусора), и для этого мы должны написать следующие 3 шага, прежде чем закрывать фигурную скобку подблока.

      1. Установить ссылки на нуль (то есть X = Y = ноль;)
      2. Call, System.gc ();
      3. Вызов, System.runFinalization ();

      Теперь правильный код для подсчета количества сотрудников (без учета стажеров)

      // Правильный код для подсчета числа
      // сотрудников без стажеров

      class Employee

      {

          private int ID;

          private String name;

          private int age;

          private static int nextId=1;

          // это сделано статическим, потому что это

          // это общее для всех и

          // общий для всех объектов

          public Employee(String name,int age)

          {

              this.name = name;

              this.age = age;

              this.ID = nextId++;

          }

          public void show()

          {

              System.out.println

              ("Id="+ID+"\nName="+name+"\nAge="+age);

          }

          public void showNextId()

          {

              System.out.println

              ("Next employee id will be="+nextId);

          }

          protected void finalize()

          {

              --nextId; 

              //В таком случае,

              // gc вызовет finalize ()

              // 2 раза для 2 объектов.

          }

      }

        
      // это закрывающая скобка класса Employee

      class UseEmployee

      {

          public static void main(String []args)

          {

              Employee E=new Employee("GFG1",56);

              Employee F=new Employee("GFG2",45); 

              Employee G=new Employee("GFG3",25);

              E.show();

              F.show();

              G.show();

              E.showNextId();

              F.showNextId();

              G.showNextId();

                    

              

                  // Это субблок для хранения

                  // все эти интерны.

                  Employee X=new Employee("GFG4",23);     

                  Employee Y=new Employee("GFG5",21);

                  X.show();

                  Y.show();

                  X.showNextId();

                  Y.showNextId();

                  X = Y = null;

                  System.gc(); 

                  System.runFinalization();

              }

          E.showNextId();

          }

      }

      Выход:

      Id=1
      Name=GFG1
      Age=56
      Id=2
      Name=GFG2
      Age=45
      Id=3
      Name=GFG3
      Age=25
      Next employee id will be=4
      Next employee id will be=4
      Next employee id will be=4
      Id=4
      Name=GFG4
      Age=23
      Id=5
      Name=GFG5
      Age=21
      Next employee id will be=6
      Next employee id will be=6
      Next employee id will be=4
       
      

      Статьи по Теме :

    • Как сделать объект пригодным для сборки мусора в Java?
    • Остров Изоляции на Яве
    • Вывод программ на Java | Набор 10 (Сборка мусора)
    • Как найти максимальную память, свободную память и общий объем памяти в Java?
    • Как работает JVM — Архитектура JVM?
    • Эта статья предоставлена Чирагом Агарвалом и Гауравом Миглани. Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

      Рекомендуемые посты:

      Сборка мусора на Java

      0.00 (0%) 0 votes