垃圾回收过程

确认对象死亡

1、引用计数法(主流虚拟机不使用该算法)
  在对象中创建一个引用计数器,每当对象被引用的时候,引用计数器加1,每当对象失去引用时,引用计数器减1。当引用计数器数值为0时,该对象则视为死亡。该算法虽然简单高效,但是有一个致命的缺陷–当两个对象互相引用的时候,这两个对象的引用同时置空,他们的引用也不会为0,因为他们之间存在互相引用。代码如下:

//该情况下无法被使用引用计数器的虚拟机回收,但是目前我找不到这种虚拟机,仅作代码展示
//没有实际效果
pulic class test{
	public Object obj = null;
	public static testGc(){
		Test test1 = new Test();
		Test test2 = new Test();
		test1.obj = test2;
		test2.obj = test1;
		test1 = null;
		test2 = null;
		System.gc();
	}
}

如果要避免这种互相引用导致的对象死亡而未被清除的缺陷,那么虚拟机需要很多额外开销才能做到。
2、可达性分析算法
  该算法主要通过计算对象是否可以通过引用链到达一类称为“GC Roots”的对象来确定对象是否存活。引用链即如果GC Root1引用了obj1,那么他们之间就存在一条逻辑上的引用链。
   GC Roots选定条件:
   1、虚拟机栈(栈帧中的本地变量表)中引用的对象。例如参数、局部变量、临时变量(直接在表达式中使用new创建出来的变量,不存在引用,在表达式结束时死亡)。
   2、方法区中的静态类型的引用对象,如引用类型静态变量。
   3、方法区中的常量,如字符串常量池中的引用。
   4、本地方法栈中的引用对象
   5、虚拟机内部的引用,如基本数据类型的Class对象,常驻的异常(OutOfMemoryError、NullPointException等),还有系统类加载器。
   6、所有被同步锁持有的对象(synchronized关键字)
   7、反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。
   8、临时性加入的对象,如在分代收集时,回收年轻代的对象时可能需要老年代中的对象来确定这些对象是否死亡。
3、引用
  在确认对象是否死亡的时候都会提到一个词叫引用,最早的引用是指存储了指向某个对象所属的具体内存位置的一组数据,这组数据关联了一个变量和真实对象。JDK1.2之后Java对引用的定义进行了扩充,将引用分成强引用、软引用、弱引用、虚引用。
   1、强引用:强引用就是代码中最普遍的赋值引用,即“Object o = new Object()”的形式。这种引用关系没有消失的话,那么垃圾收集器将不会回收该对象。
   2、软引用:软引用的引用程度低于强引用,垃圾收集器只会在必要的时候,也就是内存即将溢出时才会回收该对象,如果非必要,那么垃圾收集器将不会回收该对象。这种对象通过SoftReference类来实现。
   3、弱引用:弱引用的引用程度比软引用更低,这种引用的对象只会生存到下一次垃圾回收。当垃圾收集器开始工作时,这个对象就会被回收。通过WeakReference类来实现。
   4、虚引用:虚引用的存在与对象的生命周期无关,这种引用的存在意义仅仅是在这个对象被回收的时候收到一条系统通知。通过PhantomReference类实现。
4、回收方法区
  某些虚拟机可能不会对方法区进行回收,因为在方法区中进行一次垃圾回收的性价比很低,回收的区域远低于新生代中的垃圾回收。他的条件极为苛刻。在回收方法区中的常量相对类型变量来说比较简单,只需要判断没有任何地方引用该常量就可以进行回收了。但是对于类型信息来说,回收的条件就很多了:
   1、该类的所有实例是否都已经被回收,包括其派生出来的子类实例。
   2、该类的类加载器是否被回收,这一点极难达成,只有经过精心设计的可替换类加载器的场景下才能达成。例如OSGi、JSP的重加载等。
   3、该类的对应的Class对象没有在任何地方被引用,无法在任何地方进行反射获取该对象的信息。。
满足了这些条件,仅仅代表这些类型信息可以被回收,实际上回不回收可以通过-Xnoclassgc参数进行控制。还可以通过-verbose:class、-XX:TraceClassLoading、-XX:TraceClassUnLoading来查看类加载和卸载信息。在大量使用反射、动态代理、CGLib等字节码框架以及动态生成JSP和OSGi这类频繁自定义类加载器的场景中通常需要Java虚拟机具备类型卸载的能力,以保证不会对方法区造成过大的内存压力。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值