如何打印java类垃圾收集事件?

 java版“1.5.0_14”
 Java(TM)2运行时环境,标准版(版本1.5.0_14-b03)
 Java HotSpot(TM)服务器VM(版本1.5.0_14-b03,混合模式)

我正在尝试调试NullPointerException,我将传递对静态定义字段的引用。 更具体地说,我在Drools3工作内存实例上设置了一个全局。

workingMemory.setGlobal("log", workingMemorieslog); 

我的假设是静态收集字段静态定义的类。 (接收类必须使用WeakReference或类似的东西,我真的不知道)

你会如何建议调试这个? 我想如果我能确切知道JVM的GC何时卸载类的类/实例,那么我可以缩小错误行为的原因。 (如果不是事件的确切时间,至少得到某事确实发生的迹象)。

谢谢你,马克西姆。

要跟踪GC活动,请将其添加到java命令:

-verbose:gc -XX:+ PrintGCTimeStamps -XX:+ PrintGCDetails

你得到的NPE可能是你传递空值。

为什么不将类保留在内存中,然后查看它是否仍然存在,如果确实如此,则问题出在其他地方。 如果没有,那么你知道问题在于垃圾收集。

事实certificate,日食是这里的主要问题。

我会解释一下:

我已将webapp包装在main()方法中以测试性能。 我们使用了很多第三方代码,即Apache commons-pool。

事实certificate,我们在项目中有几个版本的jar(eclipse项目)。 我的应用程序使用这些项目有commons-pool-1.3,另一个项目有commons-pool-1.2。

使用servlet容器(Tomcat6)加载时,webapp类加载器具有第一优先级,因此它始终加载webapp版本。 当我使用main()eclipse启动应用程序时,不是非常明智的行为导出了依赖的项目jars in -classpath,而不是当前项目中的那些。

冲突发生在两个版本的commons-pool之间,这导致了一个非定义的行为 – 在一个对象借用是SOMETIMES决定创建一个新对象。 我没有查看实现代码,我认为这与GenericKeyedObjectPool(有问题的类)的静态映射保持有关。 因为创建了一个新实例,所以它确实包含对所提到的全局的空引用。

我的运气的解决方案相当简单,commons-pool仅由我的webapp使用,所以我可以从所有引用的项目中删除它,否则我想我会尝试将它们全部升级到单个版本。 如果我不能做到,我真的不知道我会做什么。 这是一个非常奇怪的eclipse默认值。

感谢您阅读和帮助。

// ps 3天。 那是我花在了解servlet替换代码中我做错了什么的时候。 结果我甚至不是问题。 :P

你有堆栈跟踪吗?

您是否尝试过使用’setGlobal’方法(假设您有代码)来查看正在发生的事情?