Class文件
本质:二进制字节流
class文件结构
指令集(256条指令)
class文件如何从硬盘加载到内存执行的
1.加载过程
class文件如何从硬盘加载到内存执行的
1.loading(class文件拿到内存)
1.双亲委派--向上找,向下委托
2.Lazyloading5种情况
new getstatic putstatic invokestatic指令,访问final变量除外
java.lang.reflect对类进行反射调用时
初始化子类的时候,父类首先初始化
虚拟机启动时,被执行的主类必须初始化
–动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化
3.ClassLoader
1.findInCache->parent.loadClass->findClass()
4.自定义类加载器
1.继承ClassLoader
2.重写findClass()->defineClass(byte[]->Class clazz)
3.加密
5.混合执行-Xmixed /纯解释执行-Xint /纯编译执行--Xcomp
1.混合使用解释器+热点代码编译
2.起始阶段采用解释执行
3.检测热点代码:-XX:CompileThreshold=10000
多次被调用的方法、循环进行编译
super(parent)方法可以指定parent
双亲委派机制的打破:
-
-
-
- 如何打破:自定义类加载器,重写loadClass()方法;
- 何时打破过?
-
-
-
-
-
-
- JDK1.2之前,自定义ClassLoader都必须重写loadClass()
- ThreadContextClassLoader可以实现基础类调用实现类代码,通过thread.setContextClassLoader指定
- 热启动,热部署
-
-
-
-
-
-
-
-
- osgi tomcat 都有自己的模块指定classloader(可以加载同一类库的不同版本)
-
-
-
-
2.linking
verification(校验是否符合class文件-- CA FE BA BE)
preparation(class文件-->静态变量赋默认值int 0;long 0;double 0.0;引用 null)
resolution(常量池中符号引用转换为可直接访问的地址)
3.initializing(静态变量赋初始值,同时执行静态语句块)
单例模式双重检查
指令重排可能导致对象初始化和应用变量赋值的先后顺序不确定,如果对象还未初始化就将引用赋值给变量,则可能有线程获取到的对象是不完整的,即半初始化的
类加载器
不同的类会被不同的类加载器加载
父加载器——》语法关系,不是父类加载器,也不是加载器的加载器
双亲委派机制(从子到父,从父到子)
安全问题、资源浪费问题(加载多次)