用 IBM 详细类装入解决问题
IBM 详细类装入选项是检查所有类装入器设置的类路径的好方法。它还可以指出指定类是由哪个类装入器装入的、从哪里装入的。这样就可以容易地看出是否装入了类的正确版本。
Javadump
Javadump(也称为 Javacore)是另一个很有用的 IBM 诊断工具;要了解它,请参阅 IBM Diagnostics Guides(请参阅 参考资料 中的链接)。当发生以下事件时,JVM 会生成 Javadump:
- 发生致命的本机异常
- JVM 用光了堆空间
- 向 JVM 发送了一个信号(例如,在 Windows 上按下了 Control-Break 或在 Linux 上按下了 Control-\)
- 调用了
com.ibm.jvm.Dump.JavaDump() 方法
触发 Javadump 的时候,会把详细信息记录到在当前工作目录下保存的一个有日期戳的文本文件中。信息包括线程、锁、堆栈等方面的数据,以及关于系统中类装入器的丰富信息。
解释 Javadump 中的类装入部分
Javadump 文件中提供的确切信息取决于 JVM 在哪个平台上运行。类装入器部分包括:
- 定义的类装入器和它们之间的关系
- 每个类装入器装入的类的列表
以下是从 Javadump 提取的类装入器信息的快照:
CL subcomponent dump routine
============================
Classpath Z(D:\jre\lib\core.jar),...
Oldjava mode false
Bootstrapping false
Verbose class dependencies false
Class verification VERIFY_REMOTE
Namespace to classloader 0x00000000
Start of cache entry pool 0x44D85430
Start of free cache entries 0x44D86204
Location of method table 0x44C23AA0
Global namespace anchor 0x00266894
System classloader shadow 0x00376068
Classloader shadows 0x44D7BA60
Extension loader 0x00ADB830
System classloader 0x00ADB7B0
Classloader summaries
12345678: 1=primordial,2=extension,3=shareable,4=middleware,
5=system,6=trusted,7=application,8=delegating
-----ta- Loader sun/misc/Launcher$AppClassLoader(0x44D7BA60),
Shadow 0x00ADB7B0,
Parent sun/misc/Launcher$ExtClassLoader(0x00ADB830)
Number of loaded classes 1
Number of cached classes 260
Allocation used for loaded classes 1
Package owner 0x00ADB7B0
-xh-st-- Loader sun/misc/Launcher$ExtClassLoader(0x44D71288),
Shadow 0x00ADB830,
Parent *none*(0x00000000)
Number of loaded classes 0
Number of cached classes 0
Allocation used for loaded classes 3
Package owner 0x00ADB830
p-h-st-- Loader *System*(0x00376068), Shadow 0x00000000
Number of loaded classes 304
Number of cached classes 304
Allocation used for loaded classes 3
Package owner 0x00000000
ClassLoader loaded classes
Loader sun/misc/Launcher$AppClassLoader(0x44D7BA60)
HelloWorld(0x00ACF0E0)
Loader sun/misc/Launcher$ExtClassLoader(0x44D71288)
Loader *System*(0x00376068)
java/io/WinNTFileSystem(0x002CD118)
java/lang/Throwable(0x002C03A8)
java/lang/IndexOutOfBoundsException(0x44D45208)
java/lang/UnsatisfiedLinkError(0x44D42D38)
....................classes left out to save space........................
[Ljava/lang/Class;(0x002CA9E8)
java/io/InputStream(0x002C9818)
java/lang/Integer$1(0x002C83E8)
java/util/Dictionary(0x002C4298) |
在这个示例中,只有三个标准类装入器:
- 系统类装入器(
sun/misc/Launcher$AppClassLoader)
- 扩展类装入器(
sun/misc/Launcher$ExtClassLoader)
- 引导类装入器(
*System*)
Classloader 汇总部分提供了系统中每个类装入器的细节。在这个系列的文章中,感兴趣的类型是基本、扩展、系统、应用程序 和 委托(用在反射中)。其他类型(共享的、中间件 和信任的)用在 Persistent Reusable JVM 中,它们超出了这个文章系列的范围(请参阅 Persistent Reusable JVM User Guide 以获得更多信息;在下面的 参考资料 一节中有一个链接)。这个汇总部分还显示了父类类装入器:系统类装入器的父类是 sun/misc/Launcher$ExtClass loader(0x00ADB830)。这个父类地址对应于父类类装入器的原始数据结构(叫作 shadow)。
类装入器装入的类部分列出了每个类装入器装入的类。在这个示例中,系统类装入器只装入了一个类 HelloWorld(在地址 0x00ACF0E0 上)。