列表实例被垃圾收集

时间:2015-11-04 13:04:16

标签: java memory garbage-collection jvm

有没有办法查看哪些实例是垃圾回收?

我尝试了-XX:+PrintGC-XX:+PrintGCDetails,但这只显示了正在释放的内存量。

编辑:在这种特殊情况下,问题是我的java进程大小正在增加,而且我使用了很多线程,而且据我所知,用于所有的内存线程不在堆大小上,而是在线程堆栈中,我不知道如何检查它的状态。

3 个答案:

答案 0 :(得分:2)

不,您不会通过日志记录从JVM中获取实例级别(类不是GC-d)信息,没有这样的设置。

了解GC如何针对特定类的实例执行操作的唯一好方法是采用memory dumps并进行比较。这样您就可以发现大量实例从一个特定的类保留。 (例如,您不小心保留了对一组流对象的引用)

更新:

既然你提到你有很多线程,那就多了一些信息。线程堆栈只包含本地原语,而不包含对象引用。所以你很可能 在heapdump中找到你的溢出对象。如果您确实认为问题是由线程数量过多引起的,那么您需要使用-Xss选项开始配置允许的堆栈大小。由于该内存即使没有被线程使用也会被保留,因此只需生成太多线程就可能会耗尽内存。

答案 1 :(得分:1)

如果要监视特定类的实例,可以让它们覆盖finalize()方法,该方法在实例被垃圾回收时调用:

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

这里有一些测试代码显示了它的实际效果:

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!");
    }
}

输出:

Goodbye, cruel world!

答案 2 :(得分:0)

  

根据我的理解,用于所有线程的内存不在堆大小上,而是在线程堆栈中,我不知道如何检查它的状态。

线程堆栈通常不是很大。但是一个线程可能会保留堆上的对象。这意味着堆栈上的变量是GC根。

Yourkit Profiler有一个GC root view。其他分析器至少应该向您显示GC根源的任何活动对象的最短路径。

或者,您可以简单地附加调试器,挂起整个VM并使用调试器堆栈和堆行走功能来检查本地变量当前持有的内容。