我们如何知道一个对象是否被 GC 标记为垃圾?
How can we know whether an object is marked as garbage by GC?
是否有任何工具可以可视化特定对象的 GC 状态?
如果您可以访问该对象,则它是不可收集的。
JVMTI 系统(Java 虚拟机工具接口)允许其他进程 link 连接到 JVM 并从中获取统计信息。这是调试器和分析器使用的; visualvm(大多数 JDKs 附带)可以做到这一点,许多商业产品也可以。他们为您提供一些 GC 见解。
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;
}
}
但是,使用该系统只是收集一般统计数据?它并不擅长 - 其他两个选项要好得多。
简短的回答是没有好的方法。
并且没有任何 方法在不(以各种方式)改变您尝试检查的对象的行为的程序中执行此操作。
“不好”的方式有:
通过使用 Reference
类型。问题是这会改变对象的生命周期,并且只会告诉您对象在 GC 运行.
的最后一个时间点的状态。
通过获取堆转储并使用堆转储分析器对其进行检查。问题是进行堆转储是一个代价高昂的“停止世界”事件,它使用大量磁盘 space 并且需要大量 RAM 来加载和分析转储。
最后,您可能不会通过这样做学到很多东西,除非您正在搜索可疑的内存泄漏。
是否有任何工具可以可视化特定对象的 GC 状态?
如果您可以访问该对象,则它是不可收集的。
JVMTI 系统(Java 虚拟机工具接口)允许其他进程 link 连接到 JVM 并从中获取统计信息。这是调试器和分析器使用的; visualvm(大多数 JDKs 附带)可以做到这一点,许多商业产品也可以。他们为您提供一些 GC 见解。
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;
}
}
但是,使用该系统只是收集一般统计数据?它并不擅长 - 其他两个选项要好得多。
简短的回答是没有好的方法。
并且没有任何 方法在不(以各种方式)改变您尝试检查的对象的行为的程序中执行此操作。
“不好”的方式有:
通过使用
的最后一个时间点的状态。Reference
类型。问题是这会改变对象的生命周期,并且只会告诉您对象在 GC 运行.通过获取堆转储并使用堆转储分析器对其进行检查。问题是进行堆转储是一个代价高昂的“停止世界”事件,它使用大量磁盘 space 并且需要大量 RAM 来加载和分析转储。
最后,您可能不会通过这样做学到很多东西,除非您正在搜索可疑的内存泄漏。