JVM
本文回答以下问题,文内可能有遗漏、错误或表达不够清晰的地方。
① 垃圾回收基本原理
② 几种常见的垃圾回收器的特性
③ CMS 常见问题
④ 年轻代和老年代常见问题
⑤ 堆外内存常见问题
⑥ jvm 内存区域划分是怎样的?
GC
① 垃圾回收基本原理
判断一个对象是否可以回收:引用计数算法和可达性分析算法。
Java 虚拟机用可达性分析算法来判断对象是否可被回收。可达性分析算法:以 GC Roots 作为起始点进行搜索,能够到达到的对象都是存活的,不可达的对象都是垃圾对象,可被回收。
垃圾收集算法有:复制算法、标记-清除算法、标记-整理算法。
② 几种常见的垃圾回收器的特性
垃圾回收器的具体组合如下:
Young | Tenured | JVM options | Description |
---|---|---|---|
Serial | Serial Old | -XX:+UseSerialGC | 单线程进行GC,适合单CPU或小内存,单机程序 |
Serial | CMS+SerialOld | -XX:-UseParNewGC -XX:+UseConcMarkSweepGC | CMS进行GC失败时,会自动使用Serial Old 策略进行GC;JDK8中声明为废弃 |
Parallel Scavenge | Serial Old | -XX:+UseParallelGC | Jdk1.5及之前版本的搭配使用 |
Parallel Scavenge | Parallel Old | -XX:+UseParallelGC -XX:+UseParallelOldGC | 适合多CPU,需要最大吞吐量,如后台计算型应用;是JDK8默认收集器策略 |
Parallel New | Serial Old | -XX:+UseParNewGC | JDK8中声明为废弃 |
Parallel New | CMS+SerialOld | -XX:+UseParNewGC -XX:+UseConcMarkSweepGC | 适合多CPU,追求低停顿时间,需快速响应如互联网应用 |
G1 | -XX:+UseG1GC | JDK9默认收集器 | |
ZGC | -XX:+UseZGC |
- 垃圾回收器特点总结
垃圾收集器 | 分类 | 作用位置 | 使用算法 | 特点 | 适用场景 | 别名 |
---|---|---|---|---|---|---|
Serial | 串行 | 新生代 | 复制算法 | 响应速度优先 | 适用于单CPU环境下的client模式 | Copy |
ParNew | 并行 | 新生代 | 复制算法 | 响应速度优先 | 多CPU环境Server模式下与CMS配合使用 | ParNew |
Parallel | 并行 | 新生代 | 复制算法 | 吞吐量优先 |
适用于后台运算而不需要太多交互的场景 | PS Scavenge |
Serial Old | 串行 | 老年代 | 标记-整理(压缩)算法 | 响应速度优先 | 适用于单CPU环境下的Client模式 | MarkSweepCompact |
Paraller Old | 并行 | 老年代 | 标记-整理(压缩)算法 | 吞吐量优先 | 适用于后台运算而不需要太多交互的场景 | PS MarkSweep |
CMS | 并发 | 老年代 | 标记-清除算法 |
响应速度优先 | 适用于互联网或B/S业务 | ConcurrentMarkSweep |
G1 | 并发、并行 | 新生代、老年代 | 标记-整理(压缩)算法 | 响应速度优先 | 响应速度优先 | G1 Mixed Generation |
- 判断JVM使用的什么垃圾收集器
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.List;
public class T {
public static void main(String args[]) {
List<GarbageCollectorMXBean> l = ManagementFactory.getGarbageCollectorMXBeans();
for(GarbageCollectorMXBean b : l) {
System.out.println(b.getName());
}
}
}
③ CMS 常见问题
● CMS(或G1)以及一些重要的参数
-XX:CMSInitiatingOccupancyFraction=n:CMS回收器机制触发垃圾回收的百分比比重,jdk8 的时候为92%。
-XX:+UseCMSInitiatingOccupancyOnly:是否每次都采用固化参数进行分配触发MajorGC
-XX:+UseCMSCompactAtFullCollection:由于 CMS GC 会产生内存碎片,且只在 Full GC 时才会进行内存碎片压缩(因此使用 CMS 垃圾回收器避免不了 Full GC)。这个参数表示开启 Full GC 时的压缩功能,减少内存碎片。
XX:CMSFullGCBeforeCompaction=n:CMS在进行n次Full GC(标记清除)之后进行一次标记整理算法
● CMS GC回收分为哪几个阶段?分别做了什么事情?CMS的优缺点?
关键点:CMS 会尽可能让 GC 线程与用户线程并发执行,可以消除长时间的 GC 停顿(STW)
优点:并发收集垃圾、低停顿
● Concurrent Model Failure 和 ParNew promotion failed什么情况下会发生?
CMS 默认只针对老年代进行垃圾回收,CMS 收集器退化会退化成单线程串行 GC 算法,造成服务长时间停顿问题,退化主要有以下几种情况:
晋升失败(promotion failed)
顾名思义,晋升失败就是指在进行 Young GC 时
,Survivor 放不下,对象只能放入 Old,但此时 Old 也放不下。(例如动态年龄判断机制导致过早晋升)
还有一种情况就是内存碎片导致的 Promotion Failed,Young GC 以为 Old 有足够的空间,结果到分配时,晋级的大对象找不到连续的空间存放。(CMS 作为 GC 收集器时,清除算法导致内存出现多段的不连续,出现大量的内存碎片)
并发模式失败(concurrent mode failure)
并发 Background CMS GC 执行期间
,Young GC 晋升的对象要放入到了 Old 区中,而此时 Old 区空间不足造成的(CMS 无法处理浮动垃圾,在CMS 的并发清理阶段,新的垃圾产生太多了)。
还有一种情况是老年代碎片化严重,无法容纳新生代提升上来的大对象。
总结:使用标记整理清除碎片和提早进行CMS操作。
④ 年轻代和老年代常见问题
● 为什么要划分成年轻代和老年代?年轻代为什么被划分成eden、survivor区域?
年轻代用来存放新近创建的对象,老年代中存放存活了很久的对象。新生代包括分为一块较大的 Eden 区和两块较小的 Survivor 区,每次使用的是 Eden 区 和一块Survivor 区,当垃圾回收的时候,清除正在使用的区域,将其中的存活对象,放入到另一个块Survivor 区,并进行整理保证空间的连续。如果对象长时间存活,则将对象移动到老年区。
● 年轻代为什么采用的是复制算法? 老年代为什么采用的是标记清除、标记整理算法?
因为新生代里绝大部分都是垃圾对象,可以使用复制算法将小部分存活对象复制到另一个区域,然后留下来的都是垃圾对象,存活的对象少,所以“复制”的次数少;老年代里绝大部分对象存活了很久,复制的代价太大且耗时久,所以采用是标记清除、标记整理算法。
⑤ 堆外内存常见问题
● 什么情况下使用堆外内存?要注意些什么?
堆外内存是存在于JVM管控之外的内存区域,Java中对堆外内存的操作,依赖于Unsafe提供的操作堆外内存的native方法。
- 使用堆外内存的原因
- 对垃圾回收停顿的改善。由于堆外内存是直接受操作系统管理而不是JVM,所以当我们使用堆外内存时,即可保持较小的堆内内存规模。从而在GC时减少回收停顿对于应用的影响。
- 提升程序I/O操作的性能。通常在I/O通信过程中,会存在堆内内存到堆外内存的数据拷贝操作,对于需要频繁进行内存间数据拷贝且生命周期较短的暂存数据,都建议存储到堆外内存。
● 堆外内存如何被回收?
见 虚引用在 java 中的典型应用、一文搞懂堆外内存(模拟内存泄漏)
内存区域
⑥ jvm 内存区域划分是怎样的?
- 程序计数器是一块很小的内存空间,它是线程私有的,可以认作为当前线程的行号指示器。
- 线程私有栈描述的是Java方法执行的内存模型。
- 本地方法栈是与虚拟机栈发挥的作用十分相似,区别是虚拟机栈执行的是Java方法,而本地方法栈则为虚拟机使用到的native方法服务,也是线程私有。
- 堆是java虚拟机管理内存最大的一块内存区域,因为堆存放的对象是线程共享的,所以多线程的时候也需要同步机制。
- 方法区同堆一样,是所有线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量,如static修饰的变量加载类的时候就被加载到方法区中。
参考文章
https://pdai.tech/md/java/jvm/java-jvm-cms-gc.html
https://www.jianshu.com/p/007052ee3773
https://cloud.tencent.com/developer/article/1545238
https://blog.51cto.com/alex4dream/2946748
网友评论