Howto print java class garbage collection events?

允我心安 提交于 2019-12-29 06:49:25

问题


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)

I'm trying to debug a NullPointerException I'm getting for passing a reference to statically defined field. To be more specific, I'm setting a global on a Drools3 working memory instance.

workingMemory.setGlobal("log", workingMemorieslog);

My assumption is that the Class where the field is statically defined is being garbage collected. (The receiving class must be using WeakReference or something like that, I don't really know)

How would you suggest to debug this? I think that if I could know exactly when JVM's GC unloads a class / instance of a class then I could narrow down on the cause of the buggy behavior. (If not the exact time of the event at least getting an indication that something did happened).

Thank you, Maxim.


回答1:


To trace GC activity add this to java command:

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

NPE that you are getting is probably you passing null value.




回答2:


Why not keep the class in memory then see if it still happens, if it does then your problem lies elsewhere. If not then you know the issue lies in garbage collection.




回答3:


It turns out that eclipse is the main issue here.

I'll explain:

I have wrapped our webapp in a main() method in order to test performance. We use a lot of 3rd party code, namely Apache commons-pool.

It turns out we had several versions of the jar spread across the projects (eclipse projects). My app which uses these projects had commons-pool-1.3, a different project had commons-pool-1.2.

When loaded using the servlet container (Tomcat6) the webapp class loader had first priority so it always loaded the webapp version. When I started the application using main() eclipse in it's not very wise behavior exported the depended projects jars in in the -classpath BEFORE the ones in the current project.

The conflict was between 2 versions of commons-pool, which caused a non defined behavior - On a object borrow is SOMETIMES decided to create a new object. I haven't looked inside the implementation code, I assume that this is something to do with a static map hold by the GenericKeyedObjectPool (the problematic class). Because a new instance was created it indeed contains a null reference to the mentioned global.

The solution to my luck was rather simple, commons-pool is being used only by my webapp so I could delete it from all referenced projects, otherwise I think i would just try to upgrade them all to a single version. If I couldn't do either I really don't know what would I've done. This is a very strange default of eclipse.

Thank you for reading and helping.

// ps. 3 days. That's the time I've spend on understanding what the hell I did wrong in my servlet replacement code. Turns out I'm not even the problem. :P




回答4:


Do you have the stack trace?

Have you tried stepping into the 'setGlobal' method (assuming you have the code) to see what's going on?



来源:https://stackoverflow.com/questions/573970/howto-print-java-class-garbage-collection-events

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!