学习笔记—JVM (2)

  在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor0区,Survivor1区“To”是空的(作为保留区域)。GC进行时,Eden区中所有存活的对象都会被复制到“To”Survivor1区,而在“From”Surivor0区中,仍存活的对象会根据他们的年龄值来决定去向。新生代中的对象每熬过一轮垃圾回收,年龄值就加1,年龄值达到年龄阀值(默认为15,可以通过-XX:MaxTenuringThreshold来设置,GC分代年龄存储在对象的header中)的对象会被移到老年代中,没有达到阀值的对象会被复制到To Survivor1区。经过这次GC后,Eden区和“From"Surivor0区已经被清空。接着将”To“区与”From“区交换,确保”To“区在一轮GC后是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,没有足够的空间存放上一次新生代收集下来的存活对象时,会将所有的对象移入老年代。

 

老年代(Old Generation)

  老年代主要存放老年代的空间用于存放长时间幸存的对象,即在新生代中经历了多次GC后仍然存活下来的对象。老年代中的对象生命周期较长,存活率比较高,在老年代中进行GC的频率相对而言较低,回收的速度也比较慢。

  通常当老年代内存被占满时进行一次Major GC。相较于minor GC, Major GC的执行次数要比minor GC要少很多,同时,Major Gc 执行的时间较Minor Gc要长。

学习笔记—JVM

 

永久代(Permanent)

  于JDK8中把存放元数据中的永久内存从堆内存中移到了本地内存(native memory)。

学习笔记—JVM

 

 

 

JVM垃圾回收算法及收集器 垃圾回收常见算法 引用计数(Reference Counting)

  比较古老的回收算法,原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。

  垃圾回收时,只用收集计数为0的对象,此算法最致命的是无法处理循环引用的问题。

复制(Copying)

  此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。

  垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中,此算法每次只处理正在使用中的对象,因此复制成本较小,同时复制过去以后还能进行相应的内存管理,不会出现”碎片“问题。

  当然,此算法的缺点也很明显,就是需要两倍内存空间。

标记-清除(Mark - Sweep)

  此算法执行分两阶段,第一阶段从引用根结点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。

学习笔记—JVM

标记-整理(Mark-Compact)

  此算法结合了”标记-清除“和”复制“两个算法的优点。也是分两个阶段,第一阶段从根结点开始标记所有被引用对象,第二阶段遍历整个堆,清除未标记对象并且把存活对象”压缩“到堆的其中一块,按顺序排放。此算法避免了”标记-清除“的碎片问题,同时也避免了”复制“算法的空间问题。

学习笔记—JVM

 

jvm中垃圾收集器

Scavenge Gc(次收集)和 Full GC(全收集)的区别

  新生代GC(Scavenge GC):Scavenge GC指发生在新生代的GC,因为新生代的java对象生命周期短,所以Scavenge GC非常频繁,一般回收速度也比较快。当Eden空间不足为对象分配内存时,会触发Scavenge GC。

  一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代Eden区进行,不会影响到老年代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden区能尽快空闲出来。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsxsd.html