简体   繁体   中英

List instances being garbage collected

Is there a way to see which instances are being garbage collected?

I tried -XX:+PrintGC and -XX:+PrintGCDetails , but that only shows the amount of memory being released.

EDIT: In this particular case, the problem is that my java process size is increasing, and I'm using a lot of threads, and for what I understand, the memory used for all the threads isn't on the heap size, but in the thread stack, which I don't know how to inspect it's state.

No, you will not get instance-level (classes are not GC-d) information out of a JVM via logging, there is no such setting for that.

The only good option to gain some insight into how GC is performing against instances of a specific class is to take memory dumps and compare them. This way you can spot huge number of instances from a specific class retained. (for example you are accidentally keeping references to a set of streamed objects)

UPDATE:

Since you mentioned that you have many threads, a bit more info on that. Thread-stack only contains local primitives, not object references. So it is very likely that you would find your overflowing objects in the heapdump. If you really believe that your problem is caused by the sheer number of your threads, that you need start configuring the the allowed stack size by using the -Xss option. Since this memory gets reserved even if not used by the thread, you might run out of memory just by spawning too many threads.

If you want to monitor instances of specific classes, you can have them override the finalize() method, which is called when the instance is being garbage collected:

@Override
protected void finalize() throws Throwable {
    super.finalize();
    // log whatever here
}

Here's some test code showing it in action:

public class MyClass {

    public static void main(String[] args) throws Exception {
        new MyClass();
        System.gc();
        Thread.sleep(1000);
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("Goodbye, cruel world!");
    }
}

Output:

Goodbye, cruel world!

and for what I understand, the memory used for all the threads isn't on the heap size, but in the thread stack, which I don't know how to inspect it's state.

Thread stacks typically aren't very large. But a thread may hold onto objects on the heap. That means variables on the stack are GC roots.

Yourkit profiler has a GC root view . Other profilers should at least show you the shortest path(s) of any live object to GC roots.

Alternatively you can simply attach a debugger, suspend the whole VM and use the debuggers stack and heap walking capabilities to inspect what's currently held by local variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM