2010-04-13 2 views
7

Я пытаюсь контролировать активность gc в своем приложении, используя флаг -verbosegc. Я вижу, что есть полные и мелкие коллекции, но есть ли способ определить (подписывать событиям/vm flags/whatever), какие объекты фактически собраны?Java GC - есть способ определить, какие объекты собраны.

Спасибо!

ответ

5

Для получения общей информации об объектах в памяти, я бы предложил вам изучить jvisualvm (он находится в папке bin вашего JDK). Он имеет много полезной информации о том, что делает VM в вашей программе, включая информацию о различных объектах и ​​состоянии памяти.

Если вы хотите что-то более конкретное, вы можете использовать WeakReferences и ReferenceQueues. Этот параметр может быть жизнеспособным, если вас интересуют только объекты нескольких типов. Вы можете создать WeakReference для объектов по мере их создания с помощью общего ReferenceQueue, а затем периодически проверять очередность очередности (обратите внимание, что в очереди указано, что объекты доступны, а не они фактически собраны):

static ReferenceQueue<MyObject> MY_QUEUE = new ReferenceQueue<MyObject>(); 
static class MyReference extends WeakReference<MyObject>{ 
    public final String name; 
    public MyReference(MyObject o, ReferenceQueue<MyObject> q){ 
    super(o, q); 
    name = o.toString(); 
    } 
} 

static{ 
    Thread t = new Thread(){ 
    public void run(){ 
     while(true){ 
     MyReference r = (MyReference)MY_QUEUE.remove(); 
     System.out.println(r.name+" eligible for collection"); 
     } 
    } 
    } 
    t.setDaemon(true); 
    t.start(); 
} 

public MyObject(){ 
    //normal init... 
    new MyReference(this, MY_QUEUE); 
} 
0

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

Вы можете записать событие на свои собственные объекты, переопределив метод finalize. Он не гарантирует 100%, что объект будет собран Мусором, поскольку он может создавать ссылки на себя, но это начало.

Взгляните на this article Это очень хороший учебник по GC.

2

метод завершения класса объекта вызывается непосредственно перед тем, как GC собирает объект. Переопределите метод в своем классе следующим образом:

@Override 
protected void finalize() throws Throwable { 
    System.out.println(this+" collected"); 
    super.finalize(); 
} 

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

+1

Также будьте осторожны, что финализаторы довольно дороги. –

+0

Хм, понятия не имею. Почему это дорого? – Feyyaz

+0

Вы никогда не можете быть уверены, что метод finalize будет вызван, поэтому этот подход не гарантирует, что вы увидите все сборки мусора. – dafmetal

0

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

Netbeans имеет отличные инструменты для изучения использования любого приложения Java (а также те, которые не работают от netbeans!). Они могут рассказать вам, сколько объектов было собрано и где используется ваша память, и еще много полезных статистика.

0

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

Чтобы проверить, какие объекты GCed вы всегда можете использовать любой профайлер как JProfiler и т.д.

3

Я не использовал этот флаг самого -XX:-TraceClassUnloading. Он предназначен для отслеживания разгрузки классов.

0

Как правило, вы не можете определить, какой объект будет восстановлен. Однако вы можете найти его подмножество, но вы должны ссылаться на них, используя ссылку «Слабый, мягкий» и «Фантом». В общем, что вы делаете, это создать объект, а затем ссылаться на него, используя одну из этих ссылок. См. Статью this.

+0

Есть ли способ определить собранные объекты с помощью инструментария? – Seffi

+0

Не знаю, о чем я знаю. В основном JMX предоставляет вам такую ​​же информацию с вашего GC-выхода. Вы можете узнать, сколько памяти освобождено. Вы можете узнать, какие объекты живут. Поэтому я предполагаю, что в теории вы можете сделать вид, как много освобождается и от исчезнувшего. Я не пробовал это. –

Смежные вопросы