导航
Java内存区域(运行时区域)
在介绍JVM的GC机制之前,首先看一下Java的运行时数据区域:
其中堆和方法区属于线程共享,而本地方法栈、程序计数器和虚拟机栈是线程私有的。
下面简要介绍各个模块的功能:
- Java堆用来存放对象实例数据和数组
- 方法区(又叫永久代)用来存储对象类型数据和回收无用的类,
- 程序计数器:每个线程都有一个独立的程序计数器用来读取字节码指令,从而实现代码的流程控制
- 虚拟机栈为虚拟机执行Java(字节码)服务
- 本地方法栈为虚拟机使用到的Native服务。虚拟机栈和本地方法栈都有可能出现StackOverFlowError 和 OutOfMemoryError 两种错误。
JVM内存分配与回收
Java的自动内存管理主要是针对对象内存,最核心的功能是堆内存汇总对象的分配与回收。
Java堆是垃圾收集器管理的主要区域,也被称作:GC 堆(Garbage Collected Heap)。目前主流的垃圾收集器采用分代回收策略。
Java堆内存
Java堆在虚拟机启动时创建,作用:存放对象实例和数组。
Java堆是垃圾收集器管理的主要区域,因此也被称为GC堆(Garbage Collected Heap)。在 JDK 7 版本及JDK 7 版本之前,堆内存被通常被分为三部分:新生代(Young Generation)、老生代(Old Generation)以及永生代(Permanent Generation)
- 新生代(Young Generation):对应图中的Eden区域
- 老生代(Old Generation)
- 永生代(Permanent Generation)
JDK 8 版本之后方法区(HotSpot 的永久代)被彻底移除了,取而代之的是元空间,元空间使用的是直接内存:
主要进行GC的区域
针对HotSpot VM的实现:
1. 部分收集
- 新生代收集(Minor GC / Young GC):只对新生代进行垃圾收集;
- 老年代收集(Major GC / Old GC):只对老年代进行垃圾收集。需要注意:Major GC在有的语境中也用于指代整堆收集。
- 混合收集(Mixed GC):对整个新生代和部分老年代进行垃圾收集。
2. 整堆收集(Full GC)
收集整个Java堆和方法区
垃圾收集算法
- 标记-清除算法
标记所有不需要回收的对象,并对所有未被标记的对象进行回收
问题:效率问题、空间问题(标记清除后会产生大量不连续的碎片)
- 复制算法
将内存分为大小相同的两块,每次使用其中的⼀块。当这⼀块的内存使用完后,就将还存活的对象复制到另⼀块去,然后再把使用的空间⼀次清理掉。这样就使每次的内存回收都是对内存区间的⼀半进行回收。
- 标记整理算法
根据老年代的特点提出的一种标记算法。标记过程仍然与“标记-清除”算法⼀样,但后续步骤不是 直接对可回收对象回收,而是让所有存活的对象向⼀端移动,然后直接清理掉端边界以外的内存。 - 分代收集算法
比如在新生代中,每次收集都会有大量对象死去,所以可以选择复制算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。
- 面试问题:
HotSpot为什么要分新生代和老年代?
回答:主要是为了提升GC的效率。
常见的垃圾收集器
Serial收集器
串行收集器是一个单线程收集器,它在进行垃圾收集工作时必须暂停其它所有的工作线程,直到它收集结束。
优点:简单、高效
ParNew收集器
ParNew收集器是Serial收集器的多线程版本。
它是许多运行在Server模式下的虚拟机的首要选择,除了Serial收集器外,只有它能与CMS收集器配合工作。
Parallel Scavenge 收集器
使用复制算法的多线程收集器
Parallel Scavenge收集器关注点是吞吐量(高效率的利用CPU),CMS等垃圾收集器更加关注用户线程的停顿时间(提高用户体验)。
如果对于收集器运行不太了解,手工优化存在困难,使用Parallel Scavenge收集器配合自适应调节策略,把内存管理优化交给虚拟机去完成也是一个不错的选择。
JDK1.8默认使用的是“Parallel Scavenge + Parallel Old”。
CMS收集器
使用标记-清除算法的收集器
CMS(Concurrent Mark Sweep)收集器是⼀种以获取最短回收停顿时间为目标的收集器。它非常注重用户体验。
CMS(Concurrent Mark Sweep)收集器是 HotSpot 虚拟机第⼀款真正意义上的并发收集器,它第⼀次实现了让垃圾收集线程与用户线程(基本上)同时工作。
运作过程如下:初始标记、并发标记、重新标记、并发清除
优点:并发收集、低停顿
缺点:
- 对CPU资源敏感
- 无法处理浮动垃圾
- 它使用的回收算法“标记-清除”算法收集结束时会导致大量空间碎片产生
G1收集器
G1 (Garbage-First) 是⼀款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器。以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征。
特点:
- 并行和并发
- 分代收集
- 空间整合:从整体看是基于“标记-整理”算法,从局部来看是基于“复制”算法实现的
- 可预测的停顿
运作过程:初始标记、并发标记、最终标记、筛选回收
G1回收器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的region