当前位置:网站首页>classLoader加载的class的回收
classLoader加载的class的回收
2022-07-28 07:08:00 【kuangxuefeng丶】
什么情况下,方法区中的类才会被回收?
1.该类所对应的所有实例对象都已经被回收了,Java堆中已经不存在该类的实例对象了。
2.加载该类的类加载器ClassLoader已经被回收了。
3.该类的Class对象没有任何引用。关于第二句的理解,加载该类的类加载器ClassLoader已经被回收了,不单单是当前创建的ClassLoader被回收了,而是要真正加载这个classClassLoader回收了(即保存当前class的ProtectionDomain被回收了),当前类才会回收;这个和双亲委派机制有关!
demo如下
package com.kxf.test;
import java.lang.reflect.Method;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
public class CustomClassLoader extends ClassLoader {
// TestHelloWorld类名
public static final String testClassName = "com.anbai.sec.classloader.TestHelloWorld";
public static final String customLoaderStaticBean = "com.kxf.test.CustomLoaderStaticBean";
// TestHelloWorld类字节码
private static final byte[] testClassBytes = new byte[] { -54, -2, -70, -66, 0, 0, 0, 51, 0, 17, 10, 0, 4, 0, 13, 8, 0,
14, 7, 0, 15, 7, 0, 16, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100,
101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 5, 104, 101, 108,
108, 111, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103,
59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 19, 84, 101, 115, 116, 72, 101, 108, 108,
111, 87, 111, 114, 108, 100, 46, 106, 97, 118, 97, 12, 0, 5, 0, 6, 1, 0, 12, 72, 101, 108, 108, 111, 32, 87,
111, 114, 108, 100, 126, 1, 0, 40, 99, 111, 109, 47, 97, 110, 98, 97, 105, 47, 115, 101, 99, 47, 99, 108,
97, 115, 115, 108, 111, 97, 100, 101, 114, 47, 84, 101, 115, 116, 72, 101, 108, 108, 111, 87, 111, 114, 108,
100, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 0, 33, 0, 3, 0, 4, 0,
0, 0, 0, 0, 2, 0, 1, 0, 5, 0, 6, 0, 1, 0, 7, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0,
0, 1, 0, 8, 0, 0, 0, 6, 0, 1, 0, 0, 0, 7, 0, 1, 0, 9, 0, 10, 0, 1, 0, 7, 0, 0, 0, 27, 0, 1, 0, 1, 0, 0, 0,
3, 18, 2, -80, 0, 0, 0, 1, 0, 8, 0, 0, 0, 6, 0, 1, 0, 0, 0, 10, 0, 1, 0, 11, 0, 0, 0, 2, 0, 12 };
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
// 只处理TestHelloWorld类
if (name.equals(testClassName)) {
ProtectionDomain pd = new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
null, this, null){
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
super.finalize();
System.out.println("CustomClassLoader ProtectionDomain finalize===");
}
};
// 调用JVM的native方法定义TestHelloWorld类
return defineClass(testClassName, testClassBytes, 0, testClassBytes.length, pd);
}
return super.findClass(name);
}
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
super.finalize();
System.out.println("CustomClassLoader finalize===");
}
}
package com.kxf.test;
import java.lang.ref.WeakReference;
public class ClassLoaderTest {
static WeakReference<Class> reference = null;
static WeakReference<Object> referenceObj = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassLoader mClassLoader = new CustomClassLoader(){
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
super.finalize();
System.out.println("mClassLoader finalize");
}
};
// referenceObj = new WeakReference<Object>(new Object());
try {
Class<?> mClass = mClassLoader.loadClass("com.kxf.test.ClassLoaderBean");
reference = new WeakReference<Class>(mClass);
Object obj = mClass.newInstance();
System.out.println("obj=="+obj);
System.out.println("mClass getClassLoader=="+mClass.getClassLoader());
System.out.println("mClass=="+mClass);
Class testClass = mClassLoader.loadClass(CustomClassLoader.testClassName);
System.out.println("testClass=="+testClass);
System.out.println("testClass getClassLoader=="+testClass.getClassLoader());
// 反射创建TestHelloWorld类,等价于 TestHelloWorld t = new TestHelloWorld();
Object testInstance = testClass.newInstance();
referenceObj = new WeakReference<Object>(testInstance);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("reference=="+reference.get());
System.out.println("referenceObj=="+referenceObj.get());
}
});
thread.start();
}
}
输出的日志如下:
ClassLoaderBean static===
[email protected]
mClass [email protected]531d72ca
mClass==class com.kxf.test.ClassLoaderBean
testClass==class com.anbai.sec.classloader.TestHelloWorld
testClass [email protected]
CustomClassLoader ProtectionDomain finalize===
CustomClassLoader finalize===
mClassLoader finalize
ClassLoaderBean finalize===
reference==class com.kxf.test.ClassLoaderBean
referenceObj==null由以上可以分析出,mClassLoader虽然被回收了,但是看的出来ClassLoaderBean并没有被回收,原因是ClassLoaderBean根本上是AppClassLoader加载的,具体的原因是ClassLoader的双亲委任模式;testClass会被回收,原因是生成的ProtectionDomain就在CustomClassLoader里面,即根本上加载testClass的ClassLoader就是mClassLoader本身。
边栏推荐
- ASP. Net core foundation VIII
- VK1620温控仪/智能电表LED数显驱动芯片3/4线接口内置 RC振荡器,提供技术支持
- uniapp上下滑屏切换支持视频和图片轮播实现,类似抖音效果
- 2022 Niuke multi school first problem solving Report
- PHPUnit在Window下如何配置
- Can‘t connect to server on ‘IP‘ (60)
- PostgreSQL is the world's most advanced open source relational database
- CarSim simulation quick start (10) - Modeling of braking system
- 思迈特软件完成C轮融资,让BI真正实现“普惠化”
- SQL注入 ----前置基础
猜你喜欢

49-OpenCv深入分析轮廓

Meituan Er Mian: why does redis have sentinels?

Half bridge buck circuit - record

中标捷报!南大通用GBase 8s中标南瑞集团2022年数据库框架项目
![[mindspire YiDianTong robot-01] you may have seen many Knowledge Q & A robots, but this is a little different](/img/d1/c2c2e4a605deddd0073a05d528733f.jpg)
[mindspire YiDianTong robot-01] you may have seen many Knowledge Q & A robots, but this is a little different
![[chart component kit] Shanghai daoning provides developers with steema download, trial and tutorial](/img/67/5373c45716ade5fbd1d3a980d8e5da.png)
[chart component kit] Shanghai daoning provides developers with steema download, trial and tutorial

MCU IO port controls 12V voltage on and off, MOS and triode circuit

Understand CDN

c语言中函数的介绍(血书20000字!!!!)

竞赛:糖尿病遗传风险检测挑战赛(科大讯飞)
随机推荐
[reprint] man Rsync translation (Chinese Manual of Rsync command)
Window 2 - > toolbar (28-1)
CarSim simulation quick start (XI) - Driver Model (1)
5张图告诉你:同样是职场人,差距怎么这么大?
JS candy xiaoxiaole game source code
二维数组及操作
模型预测控制(MPC)解析(九):二次规划的数值解(下)
pyflink连接iceberg 实践
Sparksql and flinksql create and link table records
Get the clicked line number in qtablewidget
Creation of status bar (29)
uniapp的swiper动态设置current值不生效解决办法
How to write a JMeter script common to the test team
Hcip --- LDP and MPLS Technology (detailed explanation)
HCIP---LDP和MPLS技术(详解)
js糖果消消乐小游戏源码
优炫数据库导入和导出方法
Unity切换到另一个场景的时候,发现该场景变暗了
Mysql-怎么添加用户和设置权限?
PostgreSQL:无法更改视图或规则使用的列的类型