JVM底层(未完待续)
2020-09-04 10:14:21 0 举报
AI智能生成
JVM底层(未完待续)
作者其他创作
大纲/内容
组成
栈
一个个栈帧构成(方法)
局部表量表
操作数栈
指向运行时常量池的引用
方法返回地址
附加信息
堆
新生代
Eden
Survivor(From)
Survivor(To)
老年代
永久代 (jdk8会被取消掉)
程序计数器
本地方法栈
方法区
常量池
字节码文件
有类的版本、字段、方法、接口等描述信息
垃圾回收
回收策略
复制
标记-清除(Mark-Sweep)
标记-整理 (Mark-Compact)
回收类型
Scavenge GC
主要作用新生区
Full GC
如何判断是否为垃圾
引用计数(Reference Counting)
可达性算法(GC Root Tracing)
类的加载与初始化
类的加顺序
1: 编译Java文件为Class文件
2: 加载
1: 通过“类全名”来获取定义此类的二进制字节流 (其实还有不同的方式去加载类的Class文件)
1 : 从Zip包中读取,这很常见,最终成为日后JAR、EAR、WAR格式的基础。
2 : 从网络获取(URLClassLoader),下载.class文件
3 : 运行时计算生成,这种场景使用的最多的就是动态代理技术,在java.lang.reflect.Proxy中,就是用ProxyGenerator.generateProxyClass来为特定接口生成$Prxoy的代理类的二进制字节流。
4 : 由Java源文件动态编译为.class,最常用方式!
5 : 从数据库中读取.class文件,这种场景相对少见。
2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构
3.在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口(所以我们能够通过低调用类.getClass() )
3: 校验
确保加载进来的字节流符合JVM规范
文件格式验证
元数据验证,是否符合java语言规范
字节码验证,确保程序语义合法,符合逻辑
符号引用验证,确保下一步的解析能正常执行
4: 准备
为静态变量在方法去分配内存,并设置默认值
5: 解析
虚拟机将常量池内的符号引用替换为直接引用
6: 初始化
7: 使用
8: 卸载
类的初始化条件
1: 使用new 该类实例化对象的时候
2: 读取或设置类的静态字段的时候(但被final修饰的字段,在编译器的时候被放在常量池的静态字段除外startic final)
3: 调用类的静态方法的时候
4: 使用反射Class.forName("xxxx")对此类进行反射调用的时候,该类需要初始化
5: 初始化一个类的时候,有父类,先初始化父类
(注: 1: 接口除外,父接口在调用的时候才会被初始化; 2:子类引用父类静态字段,只会引发父类初始化)
6: 被标明为启动类(包含main()方法的类要初始化)
7: 当使用JDK1.7的动态语言支持时,如果一个java.invoke.MethodHandle 实例最后解析结果REFgetStatic、REFputStatic、REF_invokeStatic 的方法句柄。并且这个方法句柄所对应的类没有初始化,则需要先触发其初始化
初始化顺序
1: 父类的静态变量与静态代码块(按顺序)
2: 子类的静态变量与静态代码块(按顺序)
3: 父类的成员变量与块赋值
4: 父类构造器
如果父类包含有参构造器,没有无参构造,则子类的构造器中一定要supper(参数),指定父类的构造器,否则报错
5: 子类的成员变量和块赋值
6: 子类的构造代码块
类的加载器
JVM提供的类加载器
启动类加载器: 最顶层的类加载器,负责加载JAVA_HOME\lib目录中的,或通过-Xbootclasspath参数指定路径中的,且被虚拟机认可(按文件名识别,如rt.jar)的类
扩展类加载器: 负责加载JAVA_HOME\lib\ext目录中的,或通过java.ext.dirs系统变量指定路径中的类库
应用程序类加载器: 也叫做系统类加载器,可以通过getSystemClassLoader()获取,负责加载用户路径(classpath)上的类库.如果没有自定义类加载器,一般这个就是默认的类加载器
tomcat中的ClassLoader
StandarClassLoader负责加载tomcat容器相关的类
WebappClassLoader: 每个web项目对应一个
双亲委派机制
如果一个类接受到类加载请求,他自己不会去加载这个请求,而且将这个类加载请求委派给父类加载器,这样一层一层传送,直到到达启动类加载器,只有当父类无法加载才会尝试自己去加载
0 条评论
下一页