【JVM专题】垃圾回收算法与垃圾收集器

一.垃 圾 回 收

 

  主要解决3个问题:

 

      1.如何判定对象为垃圾对象

           引用计数法   可达性分析法

      2.如何回收

           回收策略: 标记-清除算法    复制算法    标记-整理算法   分代收集算法           

           垃圾回收器: Serial   Parnew    Cms    G1

      3.何时回收

 

  (1)引用计数法:

 

  

 

   所以当计数值为0的时候,垃圾回收器便开始收集。但通常情况下都不使用该种策略,因器其并不能完全回

   收,例如,在堆内存中若存在对象之间的引用,便不能被回收。

 

 

 

 此时,若切断引用。在堆中的整体由于被对方引用,所以不会被回收,此时垃圾回收效率低。

 

eg:
 

  public class testGC {

      private Object instance;

    

      public testGC() {

        

          byte[] b = new byte[20*1024*1024];

    

      }

    
    public static void main(String[] args) {

        

        testGC t1 = new testGC();

        testGC t2 = new testGC();
       

        t1.instance = t2;

        t2.instance = t1;
      

        t1 = null;

        t2 = null;

        System.gc();

    }   

}

 

配置JVM参数

打印得到的日志

[GC (System.gc()) [PSYoungGen: 22446K->648K(37888K)] 42926K->21136K(123904K), 0.0019986 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 648K->0K(37888K)] [ParOldGen: 20488K->546K(86016K)] 21136K->546K(123904K), [Metaspace: 2748K->2748K(1056768K)], 0.0112990 secs] [Times: user=0.00 sys=0.02, real=0.01 secs]

Heap

 PSYoungGen      total 37888K, used 328K [0x00000000d6600000, 0x00000000d9000000, 0x0000000100000000)

  eden space 32768K, 1% used [0x00000000d6600000,0x00000000d6652030,0x00000000d8600000)

  from space 5120K, 0% used [0x00000000d8600000,0x00000000d8600000,0x00000000d8b00000)

  to   space 5120K, 0% used [0x00000000d8b00000,0x00000000d8b00000,0x00000000d9000000)

 ParOldGen       total 86016K, used 546K [0x0000000083200000, 0x0000000088600000, 0x00000000d6600000)

  object space 86016K, 0% used [0x0000000083200000,0x00000000832888d0,0x0000000088600000)

 Metaspace       used 2755K, capacity 4486K, committed 4864K, reserved 1056768K

  class space    used 295K, capacity 386K, committed 512K, reserved 1048576K

 

(2)可达性分析法

 

 通过定义GCRoot来进行从栈内存到堆中寻找,能被找到的说明是活着的对象,不能被找到的说明是垃圾对象,就要被回收。

 

 

 

   模型图:

 

 

如果切断了引用,则在堆中的整个一团,都将被当醉垃圾被回收。

 

(3)标记清除算法

 

   标记清除算法是其他算法的基础,但其本身有两个要解决的问题:效率问题  空间问题

  

 

    图中橙色表示正在被使用的空间,黄色表示可被回收的空间 。这样回收之后会造成空间的不连续,

    内存分配的时候效率就很低。又会进行多次垃圾回收。

 

(4)复制算法(主要在新生代)

     

      解决标记清除的效率问题

     

  

 

下面描述一下大概过程:模拟两个独立的区域,在上面的内存中,被标记回收的对象,清除以后。未被使用的对象,

将被连续的安排在下面的区域中,这样,当划分对象的时候,其效率大大提高。同样的,在下面的区域,被标记清除

之后,未被使用的内存也将被移动到上半部分,再被使用。

 

 

详细说明:

      内存的大概分布如下  在Eden区,只要创建新的对象,就会被扔到这个区域内。 两块Survivor为上图中

      的两块区域。Tenured Gen为内存担保,防止内存不够,作为缓冲。

 

   

     内存变化大致如下图,其被浪费的空间也仅占10%左右,这是一个可以被考虑的范围。

 

 

(5)标记整理算法(适用于老年代)

        

     对于老年代部分的内存,回收效率较低,会后垃圾较少的情况下,采用该算法最合适。

 

     

 

    标记整理算法可理解为    标记--整理--清楚三个部分,在上图中被标记的算法向右移动,

    右边的未被标记的算法也需要往左边移动,这样右边便会被整体清除回收,仅仅只是移动。

 

(6)分代收集算法

        分代收集算法并不是一个行的算法。他是有复制算法和标记整理算法的组合而实现的,

     当处于新生代,则采用复制算法。当处于老年代则采用标记整理算法。分代收集算法

     会根据不同的情况采用不同的策略。

 

(7)Serial垃圾收集器

 

       关于其特性:

 

    

 

     单线程执行模式大致如下:

 

    

    

 

        首先理解一下,单线程垃圾收集器,可能很多人会理解,单线程效率不是非常低,于是很多人就受不了

     其实不然,比如你在收集垃圾的时候又在创建垃圾,这样你就会永远无法收集完垃圾。如上图,在其他

     线程执行过程中,暂停其他线程,单独开启垃圾回收线程,当垃圾回收完毕,则可以进行其他线程,这

     样来回往复的进行垃圾收集与回收。但缺点就是,在高并发情况下,其执行效率较低。

 

(8)Parnew垃圾收集器

 

      该收集器为多线程执行模式

      使用复制算法收集(新生代)

 

     

 

   根据图可看出,与Serial垃圾收集器的不同是,在收集线程执行的过程中是多个垃圾收集线程执行,

在高并发的情况下执行效率较高,降低垃圾收集的时间,提高用户体验感。其实在某些情况下,

例如桌面客服端下,不如Serial执行效率高。

 

   要注意的一个点是,通常在使用Cms收集器对老年代进行收集的时候,不能同时使用Parallel进行收集,所以通

常情况下与parnew收集器进行组合使用。

 

(9)Parallel垃圾收集器

      

      parallel与parnew的大致功能相同,但他们的不同点在于关注点不同,即使用场景不同。

 

      

 

    parallel可进行参数的改变进行控制吞吐量:

     

    

 

 

    垃圾回收器的最大停顿时间以毫秒的单位,若时间过短,则其所能收集的内存也变小,

    但其收集的频率将变大。所以相当于一杆秤,根据应用场景不同要权衡好时间。

 

         

 

小结:

   parnew 适用于例如和用户交互的场景,垃圾收集器停顿时间短,用户体验感好。

   parallel适用于服务端开发,在高并发的情境下

 

 

全部评论

相关推荐

和蔼:在竞争中脱颖而出,厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
喜欢走神的孤勇者练习时长两年半:爱华,信华,等华,黑华
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务