Java 过度jstat“;“类装入器时间”;

Java 过度jstat“;“类装入器时间”;,java,jvm,classloader,jstat,Java,Jvm,Classloader,Jstat,我们基于Java的服务器应用程序报告了异常高的类加载时间: # jstat -class 10625 1000 Loaded Bytes Unloaded Bytes Time 4781 9165.6 114 185.2 17769.35 4781 9165.6 114 185.2 17769.85 4781 9165.6 114 185.2 17770.36 4781 9165.6 114

我们基于Java的服务器应用程序报告了异常高的类加载时间:

# jstat -class 10625 1000
Loaded  Bytes  Unloaded  Bytes     Time
  4781  9165.6      114   185.2   17769.35
  4781  9165.6      114   185.2   17769.85
  4781  9165.6      114   185.2   17770.36
  4781  9165.6      114   185.2   17771.11
  4781  9165.6      114   185.2   17771.73
这是在运行了约8小时的服务器上。jstat报告说,它花了17769秒(~4h56m!)进行类加载,每秒大约额外增加0.5-0.6秒!我们一直在跟踪一个性能问题,这是我们最好的罪犯候选人。为了确保这一点,我们检查了其他Java服务:jstat在
Time
列中显示了一个非常低的值(几秒钟,即使运行了几个小时)

我们的代码不进行常量类加载,但我们不能排除行为不端的第三方库。我们启用了
-verbose:gc
,希望能够诊断问题。但是,一旦我们的服务器加载了它的所有类(在一分钟左右的高流量内),详细的类日志就安静下来了——我们有一半希望看到jstat数据带来的一系列活动

我的问题是:

  • 这真的是一个问题吗
  • 如果是,还可以做些什么来诊断它

非常感谢您的建议。

这似乎是一个真正的问题。考虑到类加载时间增加而加载类的数量保持不变,我可能会得出这样的结论:应用程序会反复尝试加载丢失的类,例如通过
class.forName
ClassLoader.loadClass

如果缺少一个类,JVM将扫描整个类路径,然后抛出
ClassNotFoundException
。如果一个类路径包含许多JAR甚至网络URL,那么这将花费很多时间


为了进一步诊断,我建议使用
Class.forName
ClassLoader.loadClass
方法或
ClassNotFoundExceptions

这也正是我所怀疑的。然而,这样的ClassNotFoundException不会在-verbose:class输出中报告吗?如果不是这样,这可能就是原因!我会研究你的建议。谢谢。刚刚编写了一个测试程序,加载了一个不存在的类,但捕获了异常。
-verbose:class
输出中未报告任何内容!绝对是这样。再次感谢,就是这样。使用JVMTI代理记录每个ClassNotFoundException很快就指出了MVEL evaluator内部的问题,MVEL evaluator正在测试各种类型的类名以编译表达式。这样做大约3000次/秒。