java虚拟机笔记-《深入理解java虚拟机》
这篇文章内容只包含第2、3、7、8章
第二章 java内存区域与内存溢出异常
程序计数器、虚拟机栈、本地方法栈随线程而生,随线程而灭。
java虚拟机栈
java堆
方法区
运行时常量池
用于存放编译器生成的各种字面量和符号引用
程序计数器
如果线程正在执行的是Java 方法,则这个计数器记录的是正在执行的虚拟机字节码指令地址
如果正在执行的是Native 方法,则这个技术器值为空(Undefined)
第三章 垃圾收集器与内存分配策略
通过可达性分析来判断是否存活,从GCroot出发,不可达的对象称为不可达对象。
GC roots包括:
a. java虚拟机栈(栈帧中的本地变量表)中的引用的对象。
b.方法区中的类静态属性引用的对象。
c.方法区中的常量引用的对象。
d.本地方法栈中JNI本地方法的引用对象。
分配策略:
1、对象优先分配在Eden区
2、大对象直接进入老年代
3、将可能长期存活的对象直接放入老年代
第七章 虚拟机类加载机制
什么时候会开始进行类加载:
1、new一个对象的时候
2、用到反射的时候
3、初始化一个类时发现其父类还没有进行初始化
第八章 虚拟机字节码执行引擎
在类加载进行完之后进入到执行引擎执行阶段
1、运行时栈帧结构(在编译阶段就已经确定)
每一个栈帧中包含了
局部变量表:存储方法参数和方法内部定义的局部变量
方法返回地址
操作数栈:在方法执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,例如加法指令会读取栈顶的两个int型数据出栈,相加然后将结果入栈
动态连接:连接运行时常量池的符号引用。2、方法调用(从底层解释了多态)
重载方法在编译过程中就会完成识别,具体调用则是根据传入的参数的声明类型来选取。
解析调用:
方法调用的目标方法在Class文件里是一个常量池中的符号引用,在类加载的解析阶段,将其中一部分符号引用转化为直接引用,这种解析的前提是:方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行期不可变(编译期可知,运行器不可变)。这类方法的调用称为解析。解析调用一定是静态过程,在编译期间就完全确定,不会延迟到运行期再去完成。
分派调用:
静态类型的变化仅仅在使用时发生,变量本身的静态类型不会被改变,并且最终的静态类型是在编译期可知的;而实际类型变化的结果在运行期才可确定,编译器在编译程序的时候并不知道一个对象的实际类型是什么。