Java垃圾回收介绍

垃圾回收的算法之引用计数和跟搜索

1.引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用他时,+1,引用失效-1,为0的时候则能回收。

注意:Java没有采用该算法来管理内存。 可以用下面的代码测试。

        Org o1 = new Org();
	Org o2 = new Org();
	o1.parent = o2;
	o2.parent = o1;
	o1 = null;
	o2 = null;
	System.gc();


此时gc(),并没有回收o1和o2


2.根搜索算法:通过一些列名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所有走过的路径称为引用链,

当一个GC Roots没有任何引用链相连时,则证明此对象是不可用的。


如图: obj4和obj5就没有在GC Roots的引用链中,则是可被回收的对象。(用QQ画的,有点丑莫怪)。

在JAVA中,可以作为GC Roots的对象包括一下几种:

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

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

3.方法区的常量引用的对象。

4.本地方法栈(JNI)引用的对象。



再谈引用

JDK1.2之前,JAVA中的引用定义得很传统:如果reference类型的数据中存储的数值代表的是另外一块内存中的起始地址就称

这块内存代表着一个引用。 定义很纯粹,也太过狭隘,这种情况下只有 被引用和没有被引用两种状态。

对于描述一些“食之无味弃之可惜”的鸡肋型对象,就无能为力了。我们当然希望描述这样的对象:内存足够,则保留在内存中,

内存不足时,则可抛弃这些对象。

JDK1.2之后,JAVA对引用的概念进行了扩充,将引用分为[强引用(Strong Reference)、软引用(Sofr Reference)、

弱引用(Weak Reference)、虚引用(Phantom Reference)] 引用强度依次减少。 



一个对象死亡的过程

对象的死亡,GC Roots找不到它后,它并非马上就死亡,而是进入一个 F-Queue的队列中,并在稍后由一条虚拟机自动建立的、

低优先级的Finalizer线程去执行死刑。此时这个对象才死亡,但可以通过重写finalize()方法,逃出生天。

值得注意的是:finalize()方法始终只会被执行一次,如果对象下一次面临回收的时候,就是神仙难救了。

虽然救人一命胜造七级浮屠,但一般情况下,不建议重现finalize()方法救该对象,相反还要尽量避免。他不是C/C++中的析构函数。

而是Java刚诞生时为了使C/C++程序员更容易接收它做的一个妥协。它的运行代价高昂,不确定性大,无法保证各个对象的调用顺序。

另外要注意的是:他不适合做关闭外部资源之类的工作,因为完全可以用try-finally来做会更好,更即时。所以,这个可以忘掉。



回收方法区

Java虚拟机规范中说过,可以不要求虚拟机在方法区(HotSpot虚拟机中的永久代)中实现垃圾收集,而且在方法区进行垃圾收集的“性价比”一般较低。

永久代垃圾回收主要是回收:废弃的常量和无用的类。 

回收废弃的常量与回收Java堆中的对象非常类似。

回收无用的类相对而言条件比较苛刻,需要同事满足以下3个条件:

1.该类的所有实例都已被回收,即Java堆中不存在该类的任何实例。

2.加载该类的ClassLoader已被回收。

3.该类对于的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

满足以上3个条件的无用类可以进行回收,仅仅只是可以,和对象不同,不使用了就必然回收。

HotSpot虚拟机提供了-Xnoclassgc参数进行控制,还可以使用-verbose:class以及-XX:+TraceClassLoading、

-XX:+TraceClassUnLoading查看类的加载和卸载信息。 -verbose:class和-XX:+TraceClassLoading可以在Product版虚拟机使用

-XX:+TraceClassUnLoading参数需要在fastdebug版的虚拟机支持。

值得注意的是:大量使用发射、动态代理、GCLib等bytecode框架的场景,以及动态生成JSP和OSGi这类频繁自定义ClassLoader

的场景都需要虚拟机具备类卸载的功能,以保证永久代不会溢出。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值