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何时卸载类的类/实例,那么我可以缩小错误行为的原因。 (如果不是事件的确切时间,至少得到某事确实发生的迹象)。
谢谢你, 格言。
答案 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'方法(假设您有代码)来查看正在发生的事情?