如何在没有引用的情况下访问 Java 堆对象?

Posted

技术标签:

【中文标题】如何在没有引用的情况下访问 Java 堆对象?【英文标题】:How can I access Java heap objects without a reference? 【发布时间】:2010-11-25 22:26:11 【问题描述】:

我想获得对 Java 堆中所有对象的引用,即使我没有立即在我的活动线程中获得对这些对象的引用。我不需要非引用对象(那些“排队”进行垃圾收集的对象),但想获得仍在使用的任何东西。

目标是序列化和存储所有对象以实现穷人的执行状态持久化。我意识到当涉及到不同类型的瞬态时,兔子洞会变得很深,但是简单地持久化对象和加载的类定义对我很有用。

有没有办法访问堆以实现这一点?我是否忽略了更直接的方法?

【问题讨论】:

您是否正在考虑获取堆转储?还是你也想访问永久代? 我主要对从堆中访问对象感兴趣(以编程方式!)。 PermGen 会给我类定义,这也很有趣,但我试图让我的问题集中。 :-) 【参考方案1】:

我会查看instrument 包。检测您感兴趣的类,以便 ctor 注册创建的实例。如果您不想使用 java.lang.instrument,或者如果对象是通过您可以控制的东西(IoC 容器或工厂)创建的,那么您可以通过 AspectJ 来做到这一点,那么您可以做一些不那么神奇的事情。

【讨论】:

我喜欢这种方法,因为它给了我一个很好的钩子来处理对象。谢谢。【参考方案2】:

如果您想以编程方式进行堆转储,您将无法在 java.* 或 javax.* 命名空间中找到合适的 API。但是,Sun 运行时附带了 HotSpotDiagnosticMXBean,它使您能够通过将堆的内容写入磁盘中的指定文件来进行堆转储。

【讨论】:

【参考方案3】:

我建议您使用heap dump,然后使用the Eclipse Memory Analyser 进行检查。

可用的视图允许您深入到实例级别,查看对象属性。您甚至可以使用 OQL 和类似 SQL 的对象查询语言来查询对象。

下面屏幕截图中的左侧面板演示了检查字段值。

screenshot http://img181.imageshack.us/img181/4013/dominatortreegrouped.png

【讨论】:

同意 MattC - 这很酷,我想检查一下,但我主要对如何通过同一 JVM 中的代码执行此操作感兴趣。

以上是关于如何在没有引用的情况下访问 Java 堆对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Java中存储引用

如何在没有 MVC 引用的情况下将 JSON 对象返回给客户端?

多次使用相同的模拟对象/数组时,如何在没有引用问题的情况下导入模拟数据以进行测试

java对象是如何创建的

restkit,如何在没有对象映射的情况下访问对象

深入理解Java虚拟机——对象的访问定位