文章目录
1.jvm虚拟机内存模型
类加载子系统
运行时数据区: 堆
栈
本地方法栈
方法区(元空间):常量+静态变量+类元信息
程序计数器
字节码执行引擎
2.类加载过程
加载; 在硬盘上查找并通过IO读入字节码文件,使用类时才会加载,例如调用类的main()方法,new对象等等
验证: 校验字节码文件的正确性
准备: 给类的静态变量分配内存,并赋予默认值
解析: 将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针,
或句柄等(直接引用),这是所谓的静态连接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为
直接引用
初始化: 对类的静态变量初始化为指定的值,执行静态代码块
public class Tuling {
public static void main(String[] args) {
System.out.println(String.class.getClassLoader());
System.out.println(com.sun.crypto.provider.DESedeKeyFactory.class.getClassLoader().getClass().getName());
System.out.println(Tuling.class.getClassLoader().getClass().getName());
System.out.println(ClassLoader.getSystemClassLoader().getClass().getName());
}
运行结果:
null
sun.misc.Launcher$ExtClassLoadersun.misc.Launcher$AppClassLoader
sun.misc.Launcher$AppClassLoader
3.类加载器:
启动类加载器: jvm运行的位于jre/lib 目录下的核心类库 比如:rt.jar, charsets.jar等
扩展类加载器: 负责加载 位于jie的lib目录下的ext扩展目录中的jar类包
应用程序类加载器: 负责加载classpath路径下的类包,主要就是加载你自己写的那些类
自定义加载器:负责加载用户自定义路径下的类包
4. 查看jvm字节码执行情况
- javap -c Tuling.class
5. 自定义类加载器 和类加载器不生效的处理
- https://www.cnblogs.com/sunhao1234/p/12343967.html
// 自定义类加载器
package com.tuling;
/**
* Title: User
* Description: Todo
*
* @author hfl
* @version V1.0
* @date 2020-11-23
*/
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
protected void finalize() throws Throwable {
System.out.println("关闭资源,user " + name + "即将回收");
}
public void sout(){
System.out.println("=============自己的加载器加载类调用方法============");
}
}
package com.tuling;
import java.io.FileInputStream;
import java.lang.reflect.Method;
/**
* Title: MyClassLoaderTest
* Description: Todo
*
* @author hfl
* @version V1.0
* @date 2020-11-23
*/
public class MyClassLoaderTest {
static class MyClassLoader extends ClassLoader {
private String classpath;
public MyClassLoader(String classpath) {
this.classpath = classpath;
}
private byte[] loadByte(String name) throws Exception {
name = name.replaceAll("\\.", "/");
FileInputStream fis = new FileInputStream(classpath + "/" + name + ".class");
int len = fis.available();
byte[] data = new byte[len];
fis.read(data);
fis.close();
return data;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] data = loadByte(name);
return defineClass(name, data, 0, data.length);
} catch (Exception e) {
e.printstacktrace();
throw new ClassNotFoundException();
}
}
}
public static void main(String[] args) throws Exception {
MyClassLoader classLoader = new MyClassLoader("D:/test");
Class<?> clazz = classLoader.loadClass("com.tuling.User");
Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("sout", null);
method.invoke(obj, null);
System.out.println(clazz.getClassLoader().getClass().getName());
}
}
运行结果:
完
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。