В 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 с другими сложными объектами.
Он запускается, когда определяет, что пора бежать. Распространенной стратегией сборщиков мусора поколения является запуск сборщика при сбое выделения памяти поколения 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 призван стать альтернативой параллельному сборщику. Он спроектирован так, чтобы быть более предсказуемым и обеспечивать быстрое выделение с помощью дизайна областей памяти.
Это во многом зависит от того, какой сборщик мусора вы на самом деле используете, как он настроен, и от большого количества входных данных.
Для запуска сборщика мусора HotSpot (общий тот, который поставляется с Java) и как он настроен, вы можете проверить по этой ссылке
Вы можете попробовать эту небольшую программу, чтобы проверить поведение 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 /
Это полностью зависит от реальной JVM и того, что она решает делать, и в основном не в ваших руках как программисту. Седобородые упорные эксперты могут захотеть сказать JVM, что они знают лучше, но для простых смертных это должно считаться черной магией, которую лучше оставить в покое.
Что должно вас беспокоить, так это то, может ли она не отставать от оцените, что ваши программы создают и отбрасывают объекты. Если нет, то вся ваша программа останавливается на время глобальной очистки. Это приводит к очень плохому времени отклика, но редко случается с современными JVM на современных компьютерах.
Если вам интересно, что и когда происходит в вашей программе, изучите инструмент jvisualvm в последних версиях Java 6 JDK. Это действительно здорово, чтобы заглянуть внутрь.
Сборщик мусора запускается, когда ему нужны ресурсы, и на регулярной основе, на что вы можете повлиять, сообщая, когда лучше всего потратить процессор на сбор, используя System.gc ()
Вы можете помочь сборщику мусора, явно обнуляя ссылки, например, предоставив своим объектам методы init ()
, которые распределяют ресурсы, и методы cleanup ()
, которые явно очищают эти ресурсы и обнуление их ссылок. Обнуляя ссылки самостоятельно, вы избавляете сборщика мусора от необходимости находить кластеры объектов, у которых есть больше путей к корню.