java类加载流程
2021-08-19 14:50:26 10 举报
类加载到JVM内存全流程
作者其他创作
大纲/内容
JVM栈(Stack)
栈帧(main)
javac
启动类加载器(Bootstrap ClassLoader)%JRE_HOME%/lib
被动使用(被动使用不会初始化)
8大基本类型
栈帧(sum)
方法出口
1)创建类的实例,比如new一个对象2)访问某一个类或接口的静态变量,或者对该静态变量赋值 (访问类的静态变量的助记符getstatic,赋值是putstatic)。3)调用类的静态方法 (应用invokestatic助记符)。4)使用java.lang.reflect包的方法对类型进行反射调用,比如:Class.forName(“com.test.Test\
加载(双亲委派原型)
动态链接
3. 调用ClassLoader的loadClass()方法,不会导致类的初始化。public class LoadClassTest { public static void main(String[] args) { try { ClassLoader.getSystemClassLoader().loadClass(\"com.dskj.jvm.passivemode.LoadClass\"); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}class LoadClass { public static final String STR = \"Hello World\"; static { System.out.println(\"LoadClass init...\"); }}没有输出 LoadClass init...,证明了调用系统类加载器的loadClass()方法,并不会初始化LoadClass类,因为ClassLoader#loadClass()方法内部传入的resolve参数为false,表示Class不会进入到连接阶段,也就不会导致类的初始化。
其他文件生成如:JSP文件
类加载系统
操作数栈
局部变量表
从zip压缩包中读取,如:jar包,war包
4. 创建数组类对象,并不会导致引用的类初始化public class Child extends Parent { static { System.out.println(\"Child init...\"); }}// 使用 Child 引用创建个数组public static void main(String[] args) { Child[] child = new Child[1]; System.out.println(child); }输出结果:[Lcom.dskj.jvm.beidong.Child;@7852e922
refernce
线程1
网络中获取如:Web Applet
1. 通过子类引用父类的静态字段,不会导致子类的初始化2. final修饰的常量,编译时会存入调用类常量池中,本质上没有引用到定义常量的类,不会导致类的初始化动作。3. 调用ClassLoader的loadClass()方法,不会导致类的初始化。4. 创建数组类对象,并不会导致引用的类初始化
Person p=new Person(\"张三\
1. 通过子类引用父类的静态字段,不会导致子类的初始化public class Parent { static { System.out.println(\"Parent init....\"); } public static int a = 123;}public class Child extends Parent { static { System.out.println(\"Child init...\"); }}// Test类打印,子类直接调用父类的静态字段public static void main(String[] args) { System.out.println(Child.a);}输出结果:Parent init....123
自定义类加载器
2. final修饰的常量,编译时会存入调用类常量池中,本质上没有引用到定义常量的类,不会导致类的初始化动作。public class ConstClassTest { public static void main(String[] args) { System.out.println(ConstClass.STR); }}class ConstClass { static { System.out.println(\"ConstClass init...\"); } public static final String STR = \"Hello World\";}结果只会输出 Hello World,不会输出ConstClass init...,ConstClassTest类对常量ConstClass.STR的引用,实际被转化为ConstClassTest类对自身常量池的引用了。也就是说,实际上ConstClassTest的Class文件之中并没有ConstClass类的符号引用入口。编译后的结果: public static void main(String[] args) { System.out.println(\"Hello World\"); }
经过javac编译成.class文件
获取这个类的二进制字节流,将这个字节流中的数据存储到方法区中,然后生成一个代表该类的 java.lang.Class 对象(HotSpot 是把 Class 对象放在方法区中),用来访问方法区这些数据
运行时生成如:CGLIB、JDK动态代理
应用类加载器(AppClassLoader)加载当前项目 bin 目录下的所有类
本地方法栈
程序计数器
扩展类加载器(ExtClassLoader)%JRE_HOME%/lib/ext
主动使用(主动使用时使用初始化)-XX:+TraceClassLoading
returnAddress
0 条评论
下一页