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

时间:2009-02-21 23:57:12

标签: java eclipse classpath

java version "1.5.0_14"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
Java HotSpot(TM) Server VM (build 1.5.0_14-b03, mixed mode)

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

workingMemory.setGlobal("log", workingMemorieslog);

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

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

谢谢你, 格言。

4 个答案:

答案 0 :(得分:10)

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

  

-verbose:GC   -XX:+ PrintGCTimeStamps   -XX:+ PrintGCDetails

您获得的NPE可能是您传递空值。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

我会解释:

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

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

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

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

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

感谢您阅读和帮助。

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

答案 3 :(得分:0)

你有堆栈跟踪吗?

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