一、结构类型
A、堆:对象实例
B、方法区:class信息,静态变量,常量
C、栈:方法运行时信息
其中堆又分为:新生代+老年代
其中,新生代又分为Eden+From+To。一般默认8:1:1.
新生代的回收算法都是标记-复制-清除。因为都是内存操作,大部分数据都是朝生夕死,而且频繁,所以直接复制更加快速。因此采用标记-复制-清除算法回收。
为什么要将新生代分为两部分?
因为不分区,那么新生代直接到了老年代,很容易触发FullGC,需要STW。影响吞吐量(程序执行时间/(程序执行时间+回收时间))。
那又为什么将Survivor区分成2片?
因为回收算法是标记-复制-清除,要想不造成碎片化,前提就是要有一片干净连续的内存。如果我们一直维护一个空白连续空间,那么复制的时候可以直接复制,无需重新分配连续的内存。
我们常说的回收调优,一般指老年代回收,因为年轻代都是实时回收,频率也很高。
二、垃圾回收器种类
三、回收算法
标记–清除:
原理:内存进行GC时,先把需要回收的对象标记出来,然后删除对象
缺点:效率低,回收后内存不连续
标记–复制–清除:
原理:内存分为Eden+From+To=8:1:1,先标记需要回收的对象,然后把需要保留的对象复制到From区, 最后删除回收对象
优点:内存连续,适用于频繁回收对象,因此新生代堆回收一般使用此方法
标记–整理:
原理:先标记需要回收的对象,然后把保留的对象移动到界内,最后把界外的对象删除
优点:适用老年代,回收量大,但不频繁
四、标记算法(什么对象应该标记为需要回收)
a.引用计数法
一个对象创建后就开始计数,保存它被引用的次数,单次数记为0时,表示可回收
缺点:循环引用无法解决
b.GC Roots链
我们认为一个对象,只要被使用,那么就会存在一个类似树状的结构种,链接引用,当可回收时,此时的对象不会GC roots链表中,关键在于怎么确定根节点:
1):栈里面的对象:栈的对象是线程正在使用的对象,因此不可回收
2):方法区的静态变量:此时也不可回收
3):其他,如native方法正在使用的对象
只要不在上述对象的GC Roots链中的对象,我们就认为是可回收对象
五、GC回收器的结合种类
单–多:Serial + CMS
单–单:Serial + Serial Old
多–多:ParNew + CMS,Paralell Scavenge+parall old
多–单:ParNew + Serial old, Paralell Scavenge+ Serial old
注:单指单线程,多指多线程,只有一个并发CMS
说明:Paralell Scavenge 为什么不能和CMS结合,因为Paralell Scavenge不是按照分代设计的
六、GC日志分析:
下面是比较常见的日志内容:
420484.626***(JVM启动时间到目前的时间戳,秒)*: [GC [PSYoungGen(Parlell Scavenge GC): 1332969K->39723K(1335296K)***(Eden+from回收前的内存大小—>回收后的大小(总大小含未使用))***] 4084270K->2827467K(4131840K)***(堆回收前大小–堆回收后大小(堆总大小含未使用)*), 0.0851340 secs] [Times: user=0.24***(回收线程执行用户代码CPU时间CPU个数,秒)*** sys=0.00***(回收线程执行Linux内核代码CPU时间CPU个数,秒)***, real=0.09 secs***(回收线程用来I/O阻塞等待时间,秒)***]
420484.712: [Full GC [PSYoungGen: 39723K->0K(1335296K)] [ParOldGen: 2787743K->2727423K(2796544K)] 2827467K->2727423K(4131840K) [PSPermGen: 62745K->62692K(262144K)], 1.8042640 secs] [Times: user=6.78 sys=0.00, real=1.80 secs]
七、基础知识
需要对JVM堆栈信息有些了解,记住堆主要是对象及数组
堆=new+old=Eden+From+To+old
java内存=堆+栈+方法区=java进程的大小,依据不同系统有所不同
八、CMS,G1,ZGC详细回收过程
1、CMS
(STW)初始标记:寻找root根节点(STW),只有回收线程,业务线程被停止
并发标记:从根节点往下追溯对象,回收线程和业务线程同在
并发预清理:寻找在上一个步骤,并发标记产生的需要回收的数据
(STW)重新标记:将堆内剩余的数据进行扫描,进行标记
并发清理:将上述找到的数据进行清理删除
并发重置:状态重置,等待下一次回收
算法原理:标记–清除 缺点:碎片化
缺点:
1、对CPU敏感,需要多核CPU支持并发
2、碎片化:标记-清除,容易造成碎片化
当然,可以通过设置-XX:CMSFullGCBeforeCompaction进行压缩
3、悬浮垃圾:第五步并发清理的时候会造成未被标记的垃圾
Concurrent Mode Failure
2、G1
核心:通过指定吞吐量,将要要回收的对象分片(region).针对指定的吞吐量,清理有效的region。
优点:
A、指定吞吐量回收
B、内存整理:回收后会进行内存整理,不会造成内存碎片化
C、悬浮垃圾:删除的时候,STW ,业务线程被中断,就不会造成悬浮垃圾
注意下:
CMS是针对老年代的回收,G1是针对新生代和老年代的整体回收
3、ZGC