关于ClassLoader

本文详细介绍了Java中的ClassLoader机制,包括其主要职责、关键方法及其在Java2中的变化。通过理解loadClass、defineClass等方法的作用,读者可以掌握如何自定义ClassLoader及其实现原理。
1,什么是ClassLoader
与 C 或 C++ 编写的程序不同,Java 程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应于一个 Java 类。
此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader 是 JVM 中将类装入内存的那部分。
而且,Java ClassLoader 就是用 Java 语言编写的。这意味着创建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小细节。

2,一些重要的方法
A)loadClass
ClassLoader.loadClass() 是ClassLoader的入口点。该方法的定义为:Class loadClass( String name, boolean resolve );
name:JVM 需要的类的名称,如 Foo 或 java.lang.Object。
resolve:参数告诉方法是否需要解析类。

B)defineClass
defineClass方法是ClassLoader的主要诀窍。该方法接受由原始字节组成的数组并把它转换成Class对象。

C)findSystemClass
findSystemClass方法从本地文件系统中寻找类文件,如果存在,就使用defineClass将原始字节转换成Class对象,以将该文件转换成类。

D)resolveClass
可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的loadClass时可以调用resolveClass,这取决于loadClass的resolve参数的值。

E)findLoadedClass
findLoadedClass充当一个缓存:当请求loadClass装入类时,它调用该方法来查看ClassLoader是否已装入这个类,这样可以避免重新装入已存在类所造成的麻烦。

3,Java2中ClassLoader的变动
1)loadClass的缺省实现
在Java2中loadClass的实现嵌入了大多数查找类的一般方法,并使您通过覆盖findClass方法来定制它,在适当的时候findClass会调用loadClass。
这种方式的好处是可能不一定要覆盖loadClass,只要覆盖findClass就行了,这减少了工作量。

2)新方法:findClass
loadClass的缺省实现调用这个新方法。

3)新方法:getSystemClassLoader
如果覆盖findClass或loadClass,getSystemClassLoader让我们以实际ClassLoader对象来访问系统ClassLoader,而不是固定的从findSystemClass 调用它。

4)新方法:getParent
为了将类请求委托给父ClassLoader,这个新方法允许ClassLoader获取它的父ClassLoader。
### Arthas 中 ClassLoader 的用法及相关问题 Arthas 是阿里巴巴开源的一款强大的 Java 诊断工具,能够帮助开发者快速定位并解决生产环境中的各种问题[^1]。其中,ClassLoader 相关功能是其重要组成部分之一,可以用于分析和排查类加载器的相关问题。 #### 查看当前 JVM 中的 ClassLoader 结构 通过 `classloader` 命令,可以直观地展示当前 JVM 中所有的 ClassLoader 及其层次结构。此命令对于理解复杂的类加载机制非常有帮助。 ```bash classloader ``` 该命令会返回所有已加载的 ClassLoader 列表及其对应的实例数量、URL 数量等信息。 #### 查找特定类由哪个 ClassLoader 加载 当遇到类加载冲突或者需要确认某个类是由哪个具体的 ClassLoader 加载时,可以通过以下命令实现: ```bash sc <className> ``` 例如查找名为 `com.example.MyClass` 的类: ```bash sc com.example.MyClass ``` 上述命令不仅会显示目标类是否存在,还会提供加载它的具体 ClassLoader ID 和路径信息。 #### 跟踪类加载过程 为了深入研究某些特殊场景下的类加载行为,可利用 `watch` 命令监控指定方法的行为数据。比如跟踪某方法内部涉及的类加载操作: ```bash watch java.net.URLClassLoader findClass '{params,target}' -x 2 ``` 这里 `-x 2` 表示设置最大嵌套层数为两层以便获取更多上下文信息。 #### 排查 OOM (OutOfMemoryError) 类型错误 如果应用程序频繁发生内存溢出异常,并怀疑是因为过多无用的 ClassLoader 实例未释放资源所引起,则可通过下面这条指令找出可能泄漏的地方: ```bash heapdump /path/to/dump/file.hprof ``` 之后借助专业的 HPROF 文件解析软件(如 Eclipse MAT)进一步挖掘潜在原因。 #### 处理 Deadlock (死锁) 虽然这并非直接关于 ClassLoader 使用的内容,但在多线程环境下因不当同步而导致的死锁也可能间接影响到类加载流程正常运转。此时应该注意观察是否有类似 testLockThread 这样的长期处于等待状态却得不到通知的情况存在[^2]。 最后提醒一句,“纸上得来终觉浅”,实际动手实践才是掌握这些技能的关键所在[^3]!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值