Java垃圾回收机制

Java垃圾回收一般发生在Java堆中,因为堆中几乎存储了所有的Java实例。Java对象的引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)。

强引用:例如“Object obj = new Object()”,这类引用是Java程序中最普遍的。只要强引用还在,垃圾收集器就永远不会回收被引用的对象。

软引用:用来描述一些可能还用的,但并非必需的对象。在系统内存不够时,这类引用的对象将被垃圾收集器回收。JDK1.2之后提供了SoftReference 类来实现软引用。

弱引用:也是用来描述非必需对象的。被弱引用关联的对象只能生存到下次垃圾收集发生之前。当垃圾收集器工作时,无论内存是否足够,都会回收掉只被弱引用关联的对象。JDK1.2之后提供了WeakReference  类来实现软引用。

虚引用:最弱的一种引用关系,完全不对齐生存时间构成影响。也无法通过虚引用来获取一个对象实例。为一个对象设置虚引用关联仅仅是为了在这个对象被回收的时候获得一个系统通知。JDK1.2之后提供了PhantomReference 类来实现软引用。

垃圾对象的判定

垃圾对象:没有被引用的对象。

引用计数法:给对象添加一个计数器,每当该对象有一处引用,计数器+1,当引用失效时,则计数器-1。任何时刻计数器为0的对象就是不可能再被使用的。引用计数法实现简单,判定效率高,但是难以解决对象之间相互循环引用的问题。

根搜索算法:Java与C#中都是采用根搜索算法来判定对象是否存活的。基本思路是通过一系列名为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径成为引用链,当一个对象到GC Roots没有任何引用链时,就证明此对象是不可用的。在Java语音里,可作为GC Roots的对象包括下面几种:

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

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

方法区中的常量引用的对象。

本地方法栈中JNI(Native)的引用对象。

实际上,在根搜索算法中,真正宣告一个对象死亡要经历两次标记的过程:如果对象在进行根搜索算法后没有发现与GC Roots相连接的引用链,那它会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为没有必要执行。如果该对象被判定为有必要执行finalize()方法,那么这个对象会被放置在一个名为F-Queue队列中,并在稍后由一条由虚拟机自动建立,低优先级的finalizer线程去执行finalize()方法。finalize()方法是对象逃脱死亡命运的最后一次机会(一个对象的finalize()方法最多只会被系统自动调用一次),稍后GC将对F-Queue中的对象进行第二次小规模标记,如果要在finalize()方法中拯救自己,只要在finalize()方法中让该对象重引用链上的任何一个对象建立关联即可。而如果对象没有关联到任何链上的引用,那它就会被回收。

垃圾收集算法

标记-清除算法:分为“标记”和“清除”两个阶段:首先标记出需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,它的标记过程实际就是前面提到的根搜索算法中判定垃圾对象的标记过程。

标记-整理算法:复制算法比较适合于新生代,在老年代中,对象存活率比较高,如果执行较多的复制操作,效率将会变低,所以老年代一般会选用其他算法,如标记—整理算法。该算法标记的过程与标记—清除算法中的标记过程一样,但对标记后出的垃圾对象的处理情况有所不同,它不是直接对可回收对象进行清理,而是让所有的对象都向一端移动,然后直接清理掉端边界以外的内存。

复制算法:将内存平均分为两块,任意时间点,所有活动对象都被分配在同一个空间,即活动区,另一个空间则为空闲区。当空闲区内存耗尽时,JVM暂停程序运行,开启复制算法GC线程,将活动区中与GC Roots有引用链的对象复制到空闲区,剩余的垃圾对象则被回收。

分代收集:当前商业虚拟机的垃圾收集都是采用分代收集。它根据对象的存活周期不同将内存划分为几块,一般是Java堆分为新生代和老年代。在新生代中,每次垃圾收集都会有大量的对象死去,只有少量活下,因此可以用复制算法来完成收集。而老年代中因为对象存活率较高,没有额外空间对它们进行分配担保,就必须使用标记-清除算法或者标记-整理算法进行回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值