Подтвердить что ты не робот

Сборщик мусора Java - Когда он собирает?

Что определяет, когда собирает сборщик мусора? Это происходит через определенное время или после того, как определенный объем памяти исчерпан? Или существуют другие факторы?

4b9b3361

Ответ 1

Он запускается, когда он определяет, что пришло время запуска. Общей стратегией сборщиков мусора для генерации является запуск коллектора при сбое памяти поколения 0. То есть каждый раз, когда вы выделяете небольшой блок памяти (большие блоки обычно помещаются непосредственно в "старые" поколения), система проверяет, достаточно ли свободного места в кучке gen-0, а если нет, то выполняется GC, чтобы освободить место для выделения для успеха. Затем старые данные переносятся в кучу gen-1, и когда пространство заканчивается там, GC запускает коллекцию на этом, обновляя данные, которые были дольше всего до кучи gen-2, и так далее. Таким образом, GC не просто "работает". Он может работать только в куче gen-0 (и большинство коллекций будет делать именно это), или он может проверять каждое поколение, если ему действительно нужно освободить много памяти (что необходимо только довольно редко).

Но это далеко не единственная стратегия. Параметр GC работает в фоновом режиме, очищаясь во время работы программы. Некоторые GC могут выполняться как часть распределения памяти. Инкрементный коллектор может это сделать, сканируя несколько объектов при каждом распределении памяти.

Вся информация в сборщике мусора заключается в том, что он должен просто делать свое дело, не требуя ввода от пользователя. В общем, вы не можете и не должны прогнозировать, когда он будет работать.

Я считаю, что Suns JVM недавно получила GC для генерации (возможно, v1.6) Я не кодировал Java целую вечность, поэтому не уверен в этом, но я помню, что удивился не так давно, когда одним из пунктов продажи новой версии был "GC поколения". Не в последнюю очередь потому, что у .NET был один с первого дня.)

Другие JVM, конечно же, могут выбрать любую стратегию, которая им нравится.

EDIT: Вышеупомянутая часть о Java и генерации GC неверна. Подробнее см. Ниже:

В виртуальных машинах 1.0 и 1.1 использовался сборщик меток, который мог бы фрагментировать кучу после сбора мусора. Начиная с Java 1.2, виртуальные машины переключились на коллективный коллекционер, который имеет гораздо лучшее поведение дефрагментации (см. Теория и практика Java: сбор и производительность мусора).

Итак, у Java на самом деле есть генерация GC на века. Что нового в Java 6 является сборщик мусора первого мусора (G1), который доступен в Java 6u14. В соответствии с статья, претендующая на выпуск в версии 1.6.0_14: по умолчанию она не включена. Параллельный коллектор по-прежнему является GC по умолчанию и является наиболее эффективным GC для обычного бытового использования. G1 означает альтернативу для параллельного коллектора. Он спроектирован так, чтобы быть более предсказуемым и обеспечивать быстрое распределение с учетом областей областей памяти.

Ответ 2

  • Это зависит от того, как скомпилирована программа JIT.
  • Снаружи мы не можем точно сказать, когда он будет работать.
  • Это следует за некоторым алгоритмом, зависящим от этого конкретного GC.
  • Виртуальная машина Java работает на клиентской машине с некоторой виртуальной памятью в случае, если по умолчанию используется Windows 4 ГБ. Это также зависит от этой свободной виртуальной памяти в это конкретное время.

Вы можете попробовать эту небольшую программу для проверки поведения GC

public class GCTest {

   final int NELEMS = 50000;

   void eatMemory() {

      int[] intArray = new int[NELEMS];

      for (int i=0; i<NELEMS; i++) {
        intArray[i] = i;
      }

   }

   public static void main (String[] args) {

      GCTest gct = new GCTest();

      // Step 1: get a Runtime object
      Runtime r = Runtime.getRuntime();

      // Step 2: determine the current amount of free memory
      long freeMem = r.freeMemory();
      System.out.println("free memory before creating array: " + freeMem);

      // Step 3: consume some memory
      gct.eatMemory();

      // Step 4: determine amount of memory left after consumption
      freeMem = r.freeMemory();
      System.out.println("free memory after creating array:  " + freeMem);

      // Step 5: run the garbage collector, then check freeMemory
      r.gc();
      freeMem = r.freeMemory();
      System.out.println("free memory after running gc():    " + freeMem);
   }
}

возможный вывод - может быть разным в вашем случае

free memory before creating array: 4054912
free memory after creating array:  3852496
free memory after running gc():    4064184

Отметьте эту ссылку http://www.devdaily.com/java/edu/pj/pj010008/

Ответ 3

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

Для прогона сборщика мусора HotSpot (общий, который поставляется с Java) и его настройки вы можете проверить эту ссылку

Ответ 4

Это полностью зависит от фактического JVM и того, что он хочет делать, и в основном из ваших рук в качестве программиста. Greybearded die-hard эксперты могут захотеть сказать JVM, что они знают лучше, но для простых смертных это должно считаться черной матерью лучше оставить в покое.

Что вас беспокоит, так это то, что он может идти в ногу со скоростью, которую создают ваши программы и отбрасывает объекты. Если не вся ваша программа остановлена, а происходит глобальная очистка. Это оказывается очень плохим временем отклика, но редко бывает для современных JVM на современных компьютерах.

Если вам интересно, что происходит в вашей программе и когда, тогда исследуйте инструмент jvisualvm в последних версиях Java 6 JDK. Это действительно здорово заглянуть внутрь.

Ответ 5

Сборщик мусора запускается, когда ему нужны ресурсы и на регулярной основе, на которые вы можете влиять, сообщая, когда самое время потратить CPU на сбор, используя System.gc()

Вы можете помочь сборщику мусора путем явного исключения ссылок, например, предоставляя ваши методы init() для объектов, которые выделяют ресурсы и методы cleanup(), которые явно очищают эти ресурсы и обнуляют их ссылки. Путем обнуления ссылок самостоятельно вы запрещаете сборщику мусора tye от поиска кластеров объектов, которые имеют больше путей к корню.

Ответ 6

Если JVM не имеет необходимого пространства памяти для запуска, сборщик мусора запускает и удаляет ненужные объекты и выделяет память для JVM.

Ненужные объекты - это объекты, для которых нет ссылки (адреса).

Для объектов, имеющих право на сборщик мусора, есть в основном 4 точки.

  • Нулевые ссылки

    Сборщик мусора может удалить объект, когда ссылочная переменная объекта присваивается значение null в качестве значения

        A a = new A();
        a = null;
    
  • Переназначение

    Когда другому объекту присваивается эталонная переменная объект старый объект, на который ссылается, может быть удален мусором коллектор.

      A a = new A(100);
      a =new A(200);
    
  • Локальная область

    Если объект создается внутри блока, для которого объект имеет право сборщик мусора сбоку, который блокирует.

      if(condition){
    
         A a = new A();
    
      }
    
  • Выделение

    Объект может ссылаться на другой объект, но должен быть хотя бы один ссылочная (адресная) переменная для этих объектов в стеке, в противном случае все эти объекты имеют право на сборщик мусора.

          class A{
                A r;
                A(int i){
                 //something   
               }
          } 
    
          A a1 = new A(100);
          a1.r = new A(101);
          a1.r.r = new A(102);
          a1.r.r.r = a1;
    
          a1  = null //all ojects are eligible to garbage collector