【问题标题】:Hung Threads java.lang.ClassLoader.findBootstrapClass挂起的线程 java.lang.ClassLoader.findBootstrapClass
【发布时间】:2011-01-19 10:28:45
【问题描述】:

我的 J2EE 应用程序运行缓慢。我们在这种情况下进行了 Thead 转储,发现以下线程在多个转储中是可运行的,并且已在某些监视器上锁定,导致其他线程(直接或间接)等待锁定。

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) 
.....

您能否建议哪个线程没有移动并让其他线程工作?

【问题讨论】:

  • 如果您告诉 java 的版本和您使用的应用程序服务器会有所帮助。其他线程正在等待正常的类加载器锁定,但是本机方法中的特定线程如何阻塞会让我认为您可能有硬件/磁盘问题或损坏的 jar 文件。您可以在调试中启动应用程序服务器并暂停进程以查看哪个类是罪魁祸首。
  • @bestsss Java:1.5。应用服务器:WAS 7.0
  • 什么时候出现减速?刚启动后还是系统运行了一段时间或随机运行后?我本人与 WAS 并不亲密,但我会检查所有与调试相关的参数是否已关闭,并且一旦部署,没有任何内容会修改您的应用程序。看起来 websphere 可能会多次重新加载您的应用程序。
  • 你能显示更多的线程转储吗?
  • 这正是 java 1.5,我问的原因:bugs.sun.com/bugdatabase/view_bug.do?bug_id=4942470

标签: java multithreading performance jakarta-ee classloader


【解决方案1】:

为什么你的应用要加载这么多的类(锁在 loadClass 中)?预计您的应用会在初始化和预热期间加载卸载的类。

所以,我怀疑正在发生以下事情之一:

  • 您正在创建许多不同的动态代理类,而不是尝试重用它们。
  • 您创建了许多不必要的类加载器,或者至少滥用了它们。
  • 您正在启动和终止多个并行 JVM。

不用说,这些东西都非常昂贵,应该尽量避免。

【讨论】:

  • 感谢您的信息。但是我们没有使用上述 3 种东西中的任何一种。我们的应用程序是一个直接的 J2EE 应用程序,它不使用定制的类加载器并利用默认的类加载机制。另外,同意应用程序在初始化期间会加载许多类,但在实际生产环境中启动后的时间过长。我们怀疑这可能是由于 Perm-Gen 问题中的内存空间而导致的问题,但在增加 perm-gen 空间并监控它似乎很好之后,这也被排除了。
  • Java VM 将在第一次使用类时动态加载它们;虽然大多数类可能会在预热期间加载,但任何导致应用程序采用以前未采用的路径的请求都可能会加载其他类。完整的线程转储会指出是什么触发了类加载。
【解决方案2】:

如果这个线程被暂停无限期我猜它是某种循环引用(符号链接?其他?)。

如果您为加载的类启用日志记录,您可能会了解更多信息。

java -verbose:class your.Class

这可能会告诉你很多;我相信它会写入 system.out,因此您必须检查相应的日志。

【讨论】:

    【解决方案3】:

    我在 OSGI 中看到过这种情况,其中类加载器结构是一个图,而不是像通常的 J2EE 那样的树。类加载器在加载类的时候会锁住自己,所以两个线程(a,b)分别按照(x,y)和(y,x)的顺序从类加载器中加载类可能会死锁。如果静态初始化程序导致来自其他类加载器的更多类加载,则可能会发生这种情况。引导类导致从应用程序类加载器加载类的情况并不常见,但标准库中使用线程上下文加载器的任何工厂类都可以满足要求。通常的解决方案是提前加载类,可能是在应用启动期间,从而打破循环。

    【讨论】:

      猜你喜欢
      • 2012-04-18
      • 2014-09-15
      • 1970-01-01
      • 1970-01-01
      • 2012-08-02
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      相关资源
      最近更新 更多