首页 > 其他 > 详细

jvm垃圾回收

时间:2020-03-31 20:05:38      阅读:56      评论:0      收藏:0      [点我收藏+]

1、进行垃圾回收的区域

(1)堆

(2)方法区

栈是线程的私有数据,所以不进行垃圾回收

 

2、垃圾回收的时间

对这个对象不再引用的时候

public class ReferenceCountingGC {
    private static final int MB=1024*1024;
    public Object instance=null;
    private byte[] size=new byte[2*MB];

    public static void main(String[] args) {
        ReferenceCountingGC referenceCountingGC1=new ReferenceCountingGC();
        ReferenceCountingGC referenceCountingGC2=new ReferenceCountingGC();
        //循环引用
        referenceCountingGC1.instance=referenceCountingGC2;
        referenceCountingGC2.instance=referenceCountingGC1;

        referenceCountingGC1=null;
        referenceCountingGC2=null;

        System.gc();;
    }
}

技术分享图片

[Full GC (System.gc()) 
[Tenured: 0K->640K(86016K), 0.0045506 secs] 6862K->640K(124736K), 
[Metaspace: 3223K->3223K(1056768K)], 0.0046551 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
Heap
 def new generation   total 38784K, used 345K [0x0000000082200000, 0x0000000084c10000, 0x00000000ac150000)
  eden space 34496K,   1% used [0x0000000082200000, 0x0000000082256548, 0x00000000843b0000)
  from space 4288K,   0% used [0x00000000843b0000, 0x00000000843b0000, 0x00000000847e0000)
  to   space 4288K,   0% used [0x00000000847e0000, 0x00000000847e0000, 0x0000000084c10000)
 tenured generation   total 86016K, used 640K [0x00000000ac150000, 0x00000000b1550000, 0x0000000100000000)
   the space 86016K,   0% used [0x00000000ac150000, 0x00000000ac1f0040, 0x00000000ac1f0200, 0x00000000b1550000)
 Metaspace       used 3230K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 350K, capacity 388K, committed 512K, reserved 1048576K

(1)引用计数

给对象添加一个引用计数器,每当这个对象进行一次引用,计数器就加1;每当引用失效的时候,计数器就减1。当这个计数器等于0的时候,表示这个对象不会再被引用了。

 

 3、java的引用类型

(1)强引用

Object obj=new Object();这样的常规引用,只要引用还在就永远不会回收对象,在代码中有明显的new Object()这类引用,只要这种引用还在,垃圾回收器就不会回收它。就算内存不够,抛出OutOfMrmory异常也不会回收对象。

(2)弱引用

生存到下一次垃圾回收之前,无论当前内存是否够用,都回收掉被弱引用关联的对象

(3)软引用

在发生内存溢出之前,进行回收,如果这次回收之后还没有足够的内存,则报OOM。如果内存够用的情况下,不会回收,如果内存不够的话进行

(4)虚引用

不会对对象的生命周期有任何影响,也无法通过它得到对象的实例,唯一的作用也就是在垃圾回收之前收到一个系统通知

 

4、可达性分析算法

(1)可达与不可达

可达:

技术分享图片

 

 不可达:

技术分享图片

此时对象已经不再被引用了,也就是说可以被回收了。

(2)在java语言中,可以作为GC Roots的对象包括下面几种:

虚拟机栈(栈帧中的本地变量表)中引用的对象

方法区中类静态属性引用的对象

方法区中常量引用的对象

本地方法栈中JNI(即一般说的Native方法)引用的对象

 

5、标记、清除算法

(1)概念:

该算法包括“标记”和“清除”两个阶段:首先标记出所有要回收的对象,在标记完成后统一回收所有被标记的对象。

(2)缺点:

效率问题,标记和清除的效率都不高

空间问题,标记和清除之后会产生大量不连续的内存碎片

 

6、复制算法

(1)概念

将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块内存用完了,就将还存活的对象复制到另外一块上面,然后再把已经使用过的内存空间一次清理掉

(2)缺点

内存缩小为原来的一半,内存利用率太低(还要留出另外一半等着复制的时候使用)

 

7、标记整理算法

(1)概念

标记过程依旧和“标记清除算法”一样,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后把其他的内存区域清理掉。

 

8、分代算法

(1)概念

根据对象存活周期的不同将内存划分为几块

(2)回收原则

一般是把java堆分为新生代和老年代,这样可以根据各个年代的特点采用最适合的收集算法。在新生代中,每次垃圾回收的时候都会回收掉大量的对象,只有少量的对象存活,此时,选用复制算法,只需要付出少量存活对象的复制成本即可完成对象的收集,而老年代中因为对象的存活率高,没有额外空间进行分配担保,就必须使用“标记清理”算法进行回收。

堆:

技术分享图片

 

 经过几次回收之后会进入老年代

 

9、GC类型

(1)保守式GC

在回收的时候,不对数据进行记录,而是扫描内存,效率低

(2)半保守式GC

在类里面记录信息,然后扫描

(3)精确式GC

OopMap存放运行信息(类型、地址等),回收的时候只需查询Map即可

 

10、安全点:safepoint

(1)概念

在OopMap的协助下,HotSpot可以快速且准确地完成GC Roots的枚举,但如果每一条指令都生成对应的OopMap那将会需要大量的额外空间,这样GC的空间成本将会变得很高

(2)抢占式中断

在GC发生时,首先把所有的线程全部中断,如果发现有中断的地方不在安全点上,就恢复线程,让它跑到安全点上。

缺点:处于sleep或wait的时候不能到达安全点

(3)主动式中断

当GC需要中断线程的时候,不直接对线程进行操作,仅仅简单地设置一个标志,发现中断标志为真的时候就自己中断挂起

 

jvm垃圾回收

原文:https://www.cnblogs.com/zhai1997/p/12606874.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!