jvm 我们如何知道一个对象是否被GC标记为垃圾?

6ioyuze2  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(136)

是否有任何工具可以可视化特定对象上的GC状态?

pwuypxnk

pwuypxnk1#

如果你可以访问这个对象,那么它就不是可收集的。
JVMTI系统(Java虚拟机工具接口)允许其他进程链接到JVM并从JVM获取统计信息。visualvm(大多数JDK附带的)可以做到这一点,许多商业产品也可以。
JDK本身也可以这样做,使用-XX:+PrintGCDetails-read this article可以获得更多信息。
在同一个JVM中,您可以使用java.lang.ref中的类来引用对象,而不会妨碍垃圾收集。

class Test {
  private final WeakReference<String> weakRef;

  public void test() {
    String y = new String("");
    weakRef = new WeakReference<>(y);
  }

  public boolean hasItBeenCollectedYet() {
    // weak refs don't impede collection; `.get()` returns null once
    // the object begins its collection process.
    return weakRef.get() == null;
  }
}

但是,使用这个系统只是收集一般的统计数据?这并不是很好-其他两个选项要好得多。

kqqjbcuj

kqqjbcuj2#

简短的回答是,没有一个好的方法。
在一个程序中,没有任何方法可以做到这一点,而不(以各种方式)改变你试图检查的对象的行为。
“不好”的方面有:

  • 通过使用Reference类型,问题是这改变了对象的生存期,并且只告诉你在GC运行的最后一个时间点对象的状态。
  • 通过获取堆转储并使用堆转储分析器对其进行检查。问题是获取堆转储是一个代价高昂的“停止世界”事件,它使用了大量的磁盘空间,并且需要大量的RAM来加载和分析转储。

最后,除非您正在搜索可疑的内存泄漏,否则您 * 可能 * 不会通过这样做学到很多东西。

相关问题