GC是什么(分代收集算法):
1.在次数上,频繁地收集Young区:
2.在次数上,较少地收集Old区:
3.基本不动Perm区(元空间):
GC4大回收算法:
1、引用计数法(了解即可)(JVM的实现一般不采用这种方式。)
给每个对象一个计数器,减到0的时候,回收。
循环引用的举例:
2、复制算法(Copying)(常见常用)
(年轻代使用YGC或者说Minor GC进行垃圾回收,这种回收方式本质调用了复制算法)(即年轻代GC使用复制算法,复制算法不会产生内存碎片)
把伊甸园区和From区拷贝,复制到To区,也是复制算法,如第二段所示:
再详细解释一遍:
再用图举个例子:
绿色:空闲内存
红色:清理之后未被删除的对象所占内存
黄色:清理之后被删除了的对象所占内存
8:1:1
因为系统运行,会产生大量对象,所以Eden区要大。因为Eden区存活率低,只有少量会进入幸存者区,所以From和To区都小
复制算法的缺点:
1.不适用于存活率高的情况,因为需要将所有存活对象都复制一遍,并将所有引用地址重置一遍,浪费时间。
2、from和to同一时刻只能有一个在装了东西,另外一块内存区域一定为空
用于年轻代,不会产生内存碎片
3.标记清除(Mark-Sweep)(用于老年代)
没有拷贝,所以空间不浪费
但是会扫描两次(标记一次、清除一次),耗时严重、内存空间不连续,有内存碎片,再想去找连续空间就不好找了
4.标记压缩(Mark-Compact)(标记清除+整理)(用于老年代)
没有内存碎片、可以腾出连续空闲的内存空间
唯一缺点:效率不高,移动对象需要耗费更多时间(是四个算法中耗时最长的)
用哪个GC算法呢:
复制算法的内存利用率最低,因为它复制,需要腾出多余一片的空间来用于复制
所以没有最好的算法,只有最合适的GC算法——>分代收集算法(分代的垃圾回收算法)
为什么慢:
因为1.新生代和年老代的内存空间比为1:2,即说白了就是Full GC的清扫空间更大,所以更慢。
2.老年代算法
Minor GC和Full GC什么时候发生?
(1)Minor GC发生:
①当jvm无法为新的对象分配空间的时候就会发生Minor gc,所以分配对象的频率越高,也就越容易发生Minor gc。
②发生Full GC 经常会至少伴随着一次Minor GC
(2)Full GC:发生GC有两种情况,
①当老年代无法分配内存的时候,会导致Full GC
②当发生Minor GC的时候可能触发Full GC,由于老年代要对年轻代进行担保,由于进行一次垃圾回收之前是无法确定有多少对象存活,因此老年代并不能清除自己要担保多少空间,因此采取采用动态估算的方法:也就是上一次回收发送时晋升到老年代的对象容量的平均值作为经验值,这样就会有一个问题,当发生一次Minor GC以后,存活的对象剧增(假设小对象),此时老年代并没有满,但是此时平均值增加了,会造成发生Full GC