Есть способ узнать, какие объекты находятся в "старой" области Кучи

У меня длинные циклы GC. из проверок я видел, что в заложенной (старой) области Кучи слишком много объектов. Есть ли какая-либо возможность узнать, какие объекты находятся в какой области кучи, или какие-либо статические объекты об этих объектах.
Я использую Sun/Oracle HotSpot JVM (Java 6).

EDIT: немного больше информации о моей проблеме:
У меня большая куча (32 ГБ), и похоже, что даже когда старая область Heap заполнена всего на 30%, запуск GC вручную делает паузы в 15 секунд. Я хочу знать, какие объекты являются "оставшимися в живых", которые остаются в старой области, чтобы узнать, какое создание объектов нужно оптимизировать.

Ответ 1

Я не знаю ни одного инструмента/утилиты, которая работает с JVM текущего поколения.

Но флип-бок - это то, что я не вижу, как такая утилита будет полезна.

Длительные GC-времена обычно возникают, потому что ваша куча слишком заполнена. Поскольку куча приближается к 100% полной, количество времени, проведенного в GC, имеет тенденцию к экспоненциальному росту. В худшем случае куча полностью заполняется, и ваше приложение получает OutOfMemoryError. Существует два возможных решения:

  • Если основная причина заключается в том, что куча слишком мала (для размера проблемы, которую пытается решить ваше приложение), то либо увеличивайте размер кучи, либо ищите способ уменьшить рабочий набор приложения; то есть количество/размер объектов, которые должны быть "живы" во время вычисления.

  • Если основная причина - утечка памяти, найдите и исправьте ее.

В обоих случаях использование профилировщика памяти поможет вам проанализировать проблему. Но вам не нужно знать, какие объекты находятся в старом поколении. Это не имеет отношения ни к основной причине проблемы, ни к решению проблемы.


Я хочу знать, какие объекты являются "оставшимися в живых", которые остаются в старой области, чтобы узнать, какое создание объектов нужно оптимизировать.

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

Однако я все еще не думаю, что этот подход поможет. Проблема в том, что полный GC должен пересекать все доступные (жесткие, мягкие, слабые, phantom) объекты. И если у вас есть куча 32 Гб, которая заполнена на 30%, у вас все еще есть много объектов для маркировки/развертки/перемещения. Я думаю, что решение, скорее всего, будет использовать параллельный сборщик и настроить его так, чтобы он мог не отставать от скорости распределения объектов приложения.

Это также звучит так, как будто вы вызываете System.gc() непосредственно из вашего кода. Не делайте этого! Вызов System.gc() будет (обычно) заставлять JVM выполнять полную сборку мусора. Это почти гарантированно даст вам паузу. Гораздо лучше оставить JVM решить, когда запускать сборщик.

Наконец, неясно, что вы подразумеваете под "оптимизацией создания объекта". Вы имеете в виду снижение скорости создания объекта? Или вы думаете о чем-то другом, чтобы управлять удержанием долгоживущих (кэшированных?) Объектов?

Ответ 2

Трек инструментального слона может определять создание и смерть объекта, elephantTrack. При этом вы сможете выяснить, какие объекты выживают дольше, чем ожидалось, и с помощью истории методов может быть возможно получить точные объекты.

Но большая куча означает очень длительное время профиля и очень большой файл профиля.

Ответ 3

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

Я привык к Netbeans Profiler. Он не может действительно делать то, о чем вы просите, но у него есть инструмент, который может дать вам представление о том, что происходит неправильно.

Запустите приложение с Profiler, выберите Memory, затем в Live Results у вас есть столбец Generations. Он не сказал вам поколение каждого объекта, но он дает вам количество Surviving Generations. Поэтому, если число больше, чем 1, вероятно, это зависит от того, где вы живете (возможно, в оставшемся в живых), , если число всегда растет, у вас есть утечки памяти.

Ответ 4

Я не думаю, что есть какая-либо Утилита, которая может рассказать вам об отсутствии объектов в разных поколениях.

  • Один из способов. Вы можете использовать jconsole, который поставляется с jdk. с помощью jconsole вы можете подключиться к вашему приложению и контролировать все поколения, здесь вы можете получить некоторые цифры, я не уверен.
  • Другой способ - взять дамп с помощью jmap, а затем проанализировать его с помощью инструмента eclipse MAT.
  • Или вы можете запустить приложение с аргументами JVM ниже, а в журнале у вас есть информация о GC

GC logging is enabled using JVM arguments; below are the arguments I use. (Note: the log file specified as file is reset each time the VM starts.

-verbose:gc -Xloggc:file

Я думаю, что это может вам помочь.