jvm常见的垃圾回收算法,jvm工作原理和垃圾回收

  jvm常见的垃圾回收算法,jvm工作原理和垃圾回收

  00-1010堆内存划分划分区域的目的一、新区域中的垃圾收集机制二。什么时候进入老区?1经过15 GC次,进入老年区。2动态对象年龄判断。3大物体直接进入老年。4MinorGC,幸存者区域放不下太多幸存的物体。3.老年区空间配置的保障原则。4.老年区的垃圾收集算法。5.垃圾收集器概述。

  00-1010分为三部分(以下名词表示同一区):

  新生、新生代、年轻一代老年区、老年区、老年永久区和永久世代。

  00-1010的唯一目的是优化GC性能。

  如果没有生成,我们所有的对象都放在一起。当进行GC时,我们需要扫描堆的所有区域。而很多对象都是“生于早上,死于晚上”。如果所有创建的新对象都放在某个地方,那么在执行GC的时候会先回收“生于早晨,死于晚上”对象的区域,这样会腾出很多空间。

  00-1010新生分为Eden、Survivor0、Survivor1(也叫from和to),其中Eden占用80%的内存空间,每个幸存者占用10%的内存空间(比如Eden占用800M,每个幸存者占用100M)。

  1.最初创建的对象都分布在伊甸园区域。当Eden区域快满时,会触发垃圾收集Minor GC(使用复制算法的垃圾收集)。

  2.2之后。次要的GC处理,伊甸园区域的幸存对象会一次性转移到其中一个空置的幸存者区域。然后清空伊甸区,创建的对象会继续放在伊甸区,直到下一个伊甸被填满。

  3.当Eden再次填满时,它将再次启动Minor GC。清理后(Minor会清理伊甸和幸存者的内存),伊甸和幸存者中幸存的对象(此时从区域)被转移到另一个空的幸存者区域(此时到区域)。并且清除上一个对象的Eden区域和Survivor区域(现在变成To区域,而“From”和“To”会互换角色,即新的“To”是从最后一个GC之前,新的“From”是到最后一个GC之前。)

  这是复制算法的流程。需要始终保持一个幸存者区域为空,为复制算法提供垃圾收集,而这个区域的内存只占整个块的10%,其他90%的内存都可以使用,所以课件的内存利用率还是挺高的。

  

目录

 

  00-1010默认情况下,如果新区的某个对象在15次GC后还没有被回收,那么它将被转移到旧区。可以通过JVM参数“-XX:MaxTenuringThreshold”设置,默认值为15。

  00-1010这个方法不用等过GC15次。如果一批对象的总大小大于当前幸存者区域内存的50%,则这批对象在大于等于的对象将被转移到老人区域。

  例子:假设survivir 0区的两个对象经历了三次GC(年龄3),这两个对象的总大小为50M,超过了survivir 0区内存大小的一半。此时,Survivor0区域中所有大于或等于3岁的对象将被转移到老年人区域。

  00-1010有一个JVM参数-XX3360PretureSizeThreshold ,默认值为0,这意味着在任何情况下都会首先将对象分配给Eden区域。如果设置为1048576字节,则为1M。意思是当创建的对象大于1M时,会直接放入老年区,根本不会经过新老年区。原因是:大型对象在接受GC的复制算法时会降低性能。

  

堆内存的划分

Minor GC之后,残存物太多,以至于残存物区域装不下。这时,所有的对象将直接转移到老人区。

 

  

划分区域的目的

 

  2>执行每一次Minor GC前,JVM都先检查一下老年区可用的内存空间是否大于新生区所有对象的总大小。

  原因:极端情况下,Minor GC后,新生代中所有的对象都活了下来,那就会把所有新生代中的对象放入老年区中。

  如果说老年区可用内存大于新生代对象总大小,那么就可以放心的执行Minor GC。但如果老年区内存小于新生区对象的总大小,这时候就会看一个参数:-XX:HandlePromotionFailure是否设置为true了。如果为true,就进入下一次判断,看老年区可用内存是否大于之前每次Minor GC后进入老年区对象的平均大小。如果老年代可用内存小于平均大小或是参数没有设置成true,那就会直接触发Full GC,就是对老年代进行垃圾回收,腾出空间后,再进行Minor GC,相当于对新生区、老年区统一做了一次清理。三种情况递进理解:

  1.如果Minor GC后,存活的对象<Survivor区大小,直接进入Survivor区即可;

  2.如果Minor GC后,存活的对象>Survivor区大小,但<老年区可用内存,直接进入老年区;

  3.若Minor GC后,此时老年区都放不下这些存活的对象了,就会触发Full GC;如果Full GC后老年区内存还是不够用,就会导致OOM内存溢出。

  

 

  

四、老年区垃圾回收算法

标记整理算法

 

  

【原理】

 

  一开始对象都是任意分布的,在经历完垃圾回收之后,就会标记出哪些是存活对象,哪些是垃圾对象,然后就会把这些存活的对象在内存中进行整理移动,尽量都挪到一边去靠在一起,然后再把垃圾对象进行清除,这样做的好处就是避免了垃圾回收后产生的大片内存碎片。

  

 

  【缺点】

  较为耗时,比复制算法慢10倍;

  所以如果系统频繁出现Full GC,会严重影响系统性能,出现卡顿。所以JVM优化的一大问题就是减少Full GC频率。

  

 

  

五、垃圾回收器

新生区和老年区进行垃圾回收时是通过不同的垃圾回收器进行回收的

 

  Seral 和 Seral Old垃圾回收器

  分别用于回收新生区和老年区。单线程运行,垃圾回收时会停止我们系统的其他线程,再执行垃圾回收(不再使用);ParNew和CMS垃圾回收器

  分别用于新生区和老年区;多线程并发,性能更好,现在一般是线上生产系统的标配。G1垃圾回收器

  统一收集新生区和老年区,采用更加优秀的算法机制。

  

 

  

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注盛行IT的更多内容!

 

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: