文章目录
一、概述
程序在运行过程中是不断申请内存,释放内存,如果程序只是申请没有释放就会引起内存泄漏内存不足等问题。在C语言、C++中,程序员需要手动的释放内存,如果程序员粗心忘记回收,就会导致程序bug,在Java中,JVM提供自动回收内存机制GC(内存回收器),减少程序员的工作量和减低由于人为导致内存问题。
二、基本原理
将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停。
2.1 内存类型
GC回收中的内存分为新生代和老年代, 新生代与老年代的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 ) 。
-
新生代
新生代是刚刚被释放的内存存放的地方,分为 Eden、From Survivor、To Survivor三个区(8:1:1) ,一般情况,from Survior和to Survivor有一个空闲(复制算法决定的)。
-
老年代
主要存放程序中年龄较大和需要占用大量连续内存空间的对象。
2.2 GC类型
GC根据回收的内存分为两种类型:新生代 GC(Minor GC)和老年代 GC(Major GC / Full GC)
-
新生代 GC(Minor GC):指发生在新生代的垃圾收集动作,因为 Java 对象大多都具
备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。 -
老年代 GC(Major GC / Full GC):指发生在老年代的 GC,出现了 Major GC,经常
会伴随至少一次的 Minor GC(但非绝对的,在 ParallelScavenge 收集器的收集策略里
就有直接进行 Major GC 的策略选择过程) 。MajorGC 的速度一般会比 Minor GC 慢 10
倍以上。 -
Minor GC触发机制:
当年轻代满时就会触发Minor GC,这里的年轻代满指的是Eden代满,Survivor满不会引发GC -
Full GC触发机制:
当年老代满时会引发Full GC,Full GC将会同时回收年轻代、年老代,当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载
2.3对象回收流程
-
当Minor GC被触发的时候,new Generation被进行,可能触发1、2、3、4四种情况。
1)经过minorGC后,eden区的数据如果还存活,执行1或者4。当eden的对象比较大或者survicor已经满了,执行4,直接永久代;否则操作1,进入则标记回收次数,数据进入survior区,进入from还是to,由survicor决定;
2)survicor区的回收一般是使用标记复制算法,存活的数据从from进入to,或者to进入from,同时GC回收标记次数会jia1,当标记次数达到一定次数,触发3,对象进入老年代;
-
当full GC时,会触发所有的GC操作,老年代的自我回收是5。