我的J2EE应用程序运行缓慢。在这种情况下我们采用了Thead Dumps,发现以下线程在多个转储中都是Runnable,并且在某些监视器上锁定了导致其他线程(直接或间接)等待锁定。
at java.lang.ClassLoader.findBootstrapClass(Native Method)
at java.lang.ClassLoader.findBootstrapClass0(ClassLoader.java:891)
at java.lang.ClassLoader.loadClass(ClassLoader.java:301)
- locked [0x9747c360] (a sun.misc.Launcher$ExtClassLoader)
at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
- locked [0x9747c318] (a sun.misc.Launcher$AppClassLoader)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
- locked [0x9747c318] (a sun.misc.Launcher$AppClassLoader)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
.....
你能否建议哪个线程没有移动并让其他线程工作?
答案 0 :(得分:1)
为什么你的应用加载了这么多类(锁在loadClass中)?您的应用程序应该在初始化和预热期间加载卸载的类。
所以,我怀疑发生了下列事情之一:
毋庸置疑,这些东西都非常昂贵,应该尽可能避免。
答案 1 :(得分:1)
我已经在OSGI中看到过这种情况,其中类加载器结构是图形而不是通常的J2EE树。类加载器在加载类时会自行锁定,因此两个线程(a,b)分别按(x,y)和(y,x)的顺序从类加载器加载类可能会死锁。如果静态初始化程序导致更多来自其他类加载器的类加载,则可能发生这种情况。引导类从应用程序类加载器导致类加载的频率并不高,但使用线程上下文加载器的标准库中的任何工厂类都符合要求。通常的解决方案是在应用程序启动期间更早地加载类,从而打破循环。
答案 2 :(得分:0)
如果此线程暂停无限期我猜它是某种循环引用(符号链接?其他?)。
如果您为加载的类启用了日志记录,则可以了解更多信息。
java -verbose:class your.Class
这可能会告诉你很多;我相信它写入system.out所以你必须检查相应的日志。