Java垃圾回收(GC)机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgsxhdzxl/article/details/88096159

如何确定对象需要回收

  • 引用计数法

     在对象中添加一个引用计数器,当有地方引用这个对象时,计数器的值就+1,引用失效时,计数器-1,当值为0的时候,标志着对象可以回收了。  

    当A调B方法,B调A方法,这样互相引用的时候,引用计数器就会失效。

  • 可达性分析法

    从一系列成为GC Roots的对象作为起点,向下搜索,搜索所走的路径称为引用链,当一个对象到GC Roots没有任何引用链,则该对象不可达,会被判定为可回收。真正宣告对象死亡,至少要经历两次标记过程,一次是可达性分析后发现没有任何引用链,第二次是GC对对象进行标记。

    GC Roots对象包含:虚拟机栈中引用的对象;方法去静态变量成员引用的对象;方法区常量引用对象;本地方法栈JN引用的对象。

垃圾回收算法

  • 标记-清除算法

  标记阶段标记出所有需要回收的对象,清除阶段回收被标记对象所占空间。会造成内存碎片化。

                                        

  • 复制算法

    按内存容量将内存划分为等大小的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用的内存清掉。

                                  

  • 标记-整理算法

     标记阶段和标记清除算法相同,标记后不是清理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。

                             

  • 分代收集算法

    分代收集法是目前大部分JVM所采用的方法,其核心思想是根据对象存活的不同生命周期将内存划分为不同的域(新生代、老生代)。新生代用复制算法,旧生代用标记-整理算法。

垃圾收集器

  • Serial

进行垃圾回收时,会暂停所有工作线程,用一个线程去完成GC工作。

特点:高效简单,适合内存不大德尔情况。

  • Parnew

Serial的多线程版,

  • Cms

并发收集器。

  • G1  

GC过程

    所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。堆被划分为新生代和旧生代。新生代和老生代默认比例为1:2。

    新生代分为三个区,1个Eden区和2个Survivor区(分别叫from和to),默认比例为8:1:1,刚创建的对象对分到Eden区,经过第一次GC后,如果依然存活,就会被转移到Survivor, 对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。

     因为年轻代中的对象基本都是朝生夕死的(80%以上),所以在年轻代的垃圾回收算法使用的是复制算法。

     在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色。 Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。

猜你喜欢

转载自blog.csdn.net/zgsxhdzxl/article/details/88096159