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

В gdb окне можно использовать po для осмотра объекта.

данный:

NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
[dict setObject:@"foo" forKey:@"bar"];
[dict setObject:@"fiz" forKey:@"buz"];

установка точки останова после объектов добавляется, можно осмотреть то, что находится в словаре

(gdb) po dict
{
  bar = foo;
  buz = fiz;
}

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

46
задан nalo 17 October 2009 в 13:27
поделиться

5 ответов

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

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

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

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

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

РЕДАКТИРОВАТЬ: Вышеупомянутая часть о Java и GC поколений неверна. Для получения дополнительной информации см. Ниже:

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

Таким образом, Java действительно издавна имеет сборщик мусора поколений. Новое в Java 6 - это сборщик мусора Garbage-First (G1), который доступен в Java 6u14. Согласно статье о выпуске 1.6.0_14 : По умолчанию он не включен. Параллельный коллектор по-прежнему является сборщиком мусора по умолчанию и является наиболее эффективным сборщиком мусора для обычного домашнего использования. G1 призван стать альтернативой параллельному сборщику. Он спроектирован так, чтобы быть более предсказуемым и обеспечивать быстрое выделение с помощью дизайна областей памяти.

28
ответ дан 26 November 2019 в 20:41
поделиться

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

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

5
ответ дан 26 November 2019 в 20:41
поделиться
  • Это зависит от способа JIT-компиляции программы.
  • Со стороны мы не можем точно сказать, когда она будет запущена.
  • Он следует некоторому алгоритму, который зависит от этого конкретного сборщика мусора.
  • Виртуальная машина 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 /

7
ответ дан 26 November 2019 в 20:41
поделиться

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

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

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

2
ответ дан 26 November 2019 в 20:41
поделиться

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

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

1
ответ дан 26 November 2019 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: