《深入理解Java虚拟机》读书笔记
一、JVM体系结构
程序计数器:是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。
虚拟机栈:是描述java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
本地方法栈:跟虚拟机栈类似,虚拟机栈是为虚拟机执行java方法(字节码)服务,本地方法栈为虚拟机执行本地方法服务。
Java堆:是被线程共享的一块内存区域,创建的对象和数组都保存在Java堆内存中,也是垃圾收集器进行垃圾收集的最重要的内存区域。
方法区:是线程共享的内存区域,用来存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
运行时常量池:是方法区的一部分,用于保存编译期生成的各种字面量和符号引用。String的intern()会把这个字符串对象放到常量池。
所有线程共享的数据区 = 堆+方法区(hotspot JVM用永久代实现方法区)
堆内存 = 老年代+年轻代(新生代)
年轻代=Eden + S0 + S1
JVM常用内存参数说明
大小分配计算原则
数据来自《Java性能优化权威指南》
1、引用计数算法
2、可达性分析算法
GC Roots的对象包括以下几种:
1、标记-清除算法(产生碎片)
2、复制算法(新生代)
新生代将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor中还存活的对象一次性复制到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor空间。HotSpot虚拟机默认Eden和Survivor的大小比例8:1。
3、标记-整理算法 (老年代)
4、分代收集算法
1、Serial收集器
Serial收集器是一个单线程的收集器,采用复制算法,用于新生代的垃圾收集。
2、ParNew收集器
ParNew是Serial收集器的多线程版本,采用复制算法,用于新生代的垃圾收集。
3、Parallel Scavenge收集器
Parallel Scavenge收集器是新生代收集器,采用复制算法,主要是为了达到一个可控制的吞吐量(Throughput)。吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。
4、Serial Old收集器
Serial Old收集器是Serial收集器的老年代版本,用于老年代的垃圾收集。
5、Parallel Old收集器
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,用于老年代的垃圾收集。
6、CMS收集器
CMS收集器(Concurrent Mark Sweep)是以获取最短回收停顿时间为目标的收集器。是基于标记-清除算法实现的。
7、G1收集器
G1收集器(Garbage-First)将堆内存(新生代和老年代)划分成多个大小相等的独立区域(Region),根据各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需要的时间的经验值),优先回收价值最大的Region。
1、对象优先在Eden分配
2、大对象直接进入老年代
3、长期存活的对象将进入老年代
4、动态对象年龄判断
5、空间分配担保
Minor GC:清理新生代
Major GC:清理老年代
Fuu GC:清理整个堆空间(包括新生代和老年代)