.class 文件 二进制内容分析
类加载过程
prepareation: 静态变量赋默认值
resolution: 常量池符号引用,变成直接引用(直接可以访问的内存地址)
initializing:静态变量赋初始值
classloader 加载类
所有的类加载器,都需要继承ClassLoader 顶级抽象类
类加载到内存会创建两个对象,1 . class 类文件,2 类对象
这块数据(方法区)存放在 metaspace (1.8 及以上版本), Permanent Generation (永久代)
类加载器
classloader 如果为 null , 就是用 Bootstrap classloader 加载的( bootstrap 是c++ 写的一个模块,java里面没有一个class和其对应,所以返回 null)。
ExtClassLoader 对应的是 Extension classloader加载的
import org.junit.Test;
public class TestClassloader {
@Test
public void test1() {
System.out.println(String.class.getClassLoader());
System.out.println(sun.awt.HKSCS.class.getClassLoader());
System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
System.out.println(this.getClass().getClassLoader());
}
}
// 结果
null
null
sun.misc.Launcher$ExtClassLoader@65b54208
sun.misc.Launcher$AppClassLoader@18b4aac2
自底向上检查该类是否已经加载 parent 方向
自顶向下进行实际查找和加载 child 方向
why 使用双亲委派机制 ? 主要为了安全
父加载器不是 “类加载器的加载器”, 也不是"类加载器的父类加载器"
@Test
public void test2() {
System.out.println(TestClassloader.class.getClassLoader());
System.out.println(TestClassloader.class.getClassLoader().getClass().getClassLoader());
System.out.println(TestClassloader.class.getClassLoader().getParent());
System.out.println(TestClassloader.class.getClassLoader().getParent().getParent());
}
// 结果
sun.misc.Launcher$AppClassLoader@18b4aac2
null
sun.misc.Launcher$ExtClassLoader@65b54208
null
-XX:compileThreshold=10000
以上资料来自:马士兵大学学习资料学习