您的位置:首页 > 编程语言 > Java开发

读书笔记——深入理解虚拟机

2016-08-05 23:34 162 查看

自动内存管理机制

Java与C++之间有一堵由内存分配和垃圾收集所围成的“高强”,墙外面的人想进去,强里面的人却想出来。

java内存区域与内存溢出异常



每个线程私有

程序计数器:可以看做是当前线程所执行的字节码的行号指示器。

Java虚拟机栈:虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

本地方法栈:虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。

共享公有

堆:存放对象实例

方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

运行时常量(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。

垃圾收集器GC(Garbage Collection)与内存分配策略

对象已死?

引用计数算法(Reference Counting):无法解决循环引用的问题。

可达性分析算法(Reachability Analysis):判断对象的引用链是否可达。

垃圾收集算法

标记-清除(Mark-Sweep):效率不高;空间碎片。



复制算法(Copy):内存等容量分为A、B两块,每次使用其中一块,当这块内存使用完后,将还存活的对象复制到另外一块上面,并对当前半区进行内存回收。将内存缩小为以前的一半。



标记-整理(Mark-Compact):



分代收集算法(Generational Collection):更具对象存活周期的不同,一般分为新生代和老年代。

虚拟机执行子系统

代码编译的结果从本地机器码转为字节码,是存储格式发展的一小步,却是编程语言发展的一大步

类文件结构

待续。。。

虚拟机类加载机制



类加载的过程

加载

通过一个类的权限定名(ZIP、网络、运行时生成动态代理——java.lang.reflect.Proxy)来获取定义此类的二进制字节流;

将这个字节流所代表的静态存储结构转化为方法区的二进制字节流;

在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

非数组类可以通过类加载器控制,而数组类由Java虚拟机直接创建。

连接阶段:

验证

目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,避免不会危害虚拟机自身的安全。

主要分为:文件格式验证、元数据验证、字节码验证、符号引用验证。

准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配

通常情况下初始化仅包括被static修饰的类变量相应的零值;被
final
修饰的类变量被初始化时会进行赋值操作。



public static int value = 123;  // value = 0
public static final int value = 123; // value = 123


解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符

符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。

直接引用(Direct References):可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。

初始化

初始化阶段是执行类构造器方法的过程

虚拟机字节码执行引擎



- 基于栈的指令集与基于寄存器的指令集
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 虚拟机