1. 什么是垃圾
没有任何引用指向的一个对象或者多个对象(循环引用)
2.如何定位垃圾
- 引用计数(无法处理循环引用问题)
- 根搜索算法(root searching)
重点:掌握哪些是根
3.常见垃圾回收算法
-
标记清除 -缺点: 位置不连续,会产生碎片
-
拷贝算法 - 优点:没有碎片 , 缺点:浪费空间
-
标记压缩 - 优点:没有碎片 ,缺点:效率偏低
4.JVM内存分代模型
-
部分垃圾回收器使用的模型
-
新生代+老年代+永久代(jdk 1.7)/元数据区(jdk 1.8 Metaspace)
- 永久代元数据- 存放Class
- 永久代必须指定大小限制, 元数据区可以设置,也可以不设置(无上限,受限于物理内存)
- 字符串常量 1.7保存在永久代, 1.8保存在堆中
- 方法区是逻辑概念(逻辑分区) 1.7对应永久代 1.8对应元数据
-
新生代 = Eden + 2个survivor区
- YGC回收之后, 大多数对象会被回收, 活着的对象进入survivor0
- 再一次YGC之后, 仍然活着的对象进入survivor1
- 再次YGC , eden +s1 -> s0 (可理解为在s1与s0来回移动)
- 年龄足够,进入老年代
- s区如果装不下直接进入老年代
-
老年代
- 顽固分子
- 老年代满了,出发FGC Full GC
-
GC Tuning (Generation),
- 调优的目标: 尽量减少FGC
- MinoirGC=YGC
- MajorGC=FGC
内存模型
5常见垃圾回收器
- 垃圾回收器的发展路线, 是随着内存越来越大的过程而演进, 从分代算法演化到不分代算法
- JDK诞生 Serial追随提高效率, 诞生了PS , 为了配合CMS, 诞生了PN, CMS是1.4版本后期引入, CMS是里程碑式的GC, 它开启了并发回收的过程, 但是CMS毛病较多, 目前任何一个JDK版本默认是CMS并发回收是因为无法忍受STW
- Serial 年轻代 - 串行回收(单线程)
- ParallelScavenge 年轻代-并行回收(多线程)
- ParNew 年轻代 配合CMS 并行回收
- SerialOld 老年代 串行
- ParallelOld 老年代 并行
- ConcurrentMarkSweep 老年代 并发的垃圾回收和应用程序同时运行,降低STW的时间(200ms以内)
- G1 (STW降低到10ms以内) --(概念分代,物理不分代)
- ZGC (STW降低到1ms以内) PK C++ (不分代垃圾回收器)
- Shenandoah (不分代垃圾回收器)
- Eplison (啥也不干的垃圾回收器)
JDK1.8默认的垃圾回收器是 ParallelScavenge+ParallelOld(常见的垃圾回收器调优)
垃圾回收器
6.JVM调优第一步,了解生产环境下的垃圾回收器组合
-
JVM的命令行参考:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
-
JVM参数分类
标准命令: -开头, 所有的HotSpot都支持
非标准命令: -X开头, 特定版本的HotSpot支持特定命令
不稳定命令: -XX开头, 下个版本可能取消
常用参数:- -XX:+PrintFlagsFinal
设置值(最终生效值) - -XX:+PrintFlagsInitial
默认值 - -XX:+PrintCommandLineFlags
当前使用的命令行参数
- -XX:+PrintFlagsFinal