JVM-垃圾回收

3.1概述

什么叫做垃圾?

创建一个对象,有一个句柄指向对象,当句柄指向别的对象,没有地址指向这个对象了,再也找不到这个对象了,就可以称之为垃圾。这时候就需要回收

什么是垃圾回收?

就是回收那些没有地址指向的对象,将那些无用的数据标记为无效,后续再创建对象是就会再次使用这些标记为无效的区域。

如何进行垃圾回收?

就是将垃圾所占的内存标记为无效

3.2 可达性分析算法(现在在使用的)

当前的主流编程语言都是通过可达性分析(Reachability Analysis)算法来判定对象是否存活的

基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。

GC Roots区中是方法区中静态变量或者方法区中栈中变量

3.3 引用计数法

在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。

优点:原理简单,判定效率也很高。

缺点:有很多例外情况要考虑,必须要配合大量额外处理才能保证正确地工作

例如:两个对象相互指向时,这时两个对象都不会被引用了,但是不能被标记为无效数据。

public static void testGC() {

ReferenceCountingGC objA = new ReferenceCountingGC();

ReferenceCountingGC objB = new ReferenceCountingGC();

objA.instance = objB;

objB.instance = objA;

objA = null;

objB = null // 假设在这行发生GC,objA和objB就不能被回收

System.gc();

}

3.4 引用

Java在1.2 版本前就只有狭义的引用的概念,就是当reference中存的是另一块内存的地址,就是引用,在1.2版本之后就拓宽的引用的概念,将引用分为强引用,软引用,弱引用,虚引用。

·强引用是最传统的“引用”的定义,是指在程序代码之中普遍存在的引用赋值,即类似“Objectobj=new Object()”这种引用关系。无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。

·软引用是用来描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。在JDK 1.2版之后提供了SoftReference类来实现软引用。

·弱引用也是用来描述那些非必须对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2版之后提供了WeakReference类来实现弱引用。

·虚引用也称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。Threadlocal的内部是虚引用。在JDK 1.2版之后提供了PhantomReference类来实现虚引用。

3.5 垃圾回收的过程

垃圾回收并不是立即死亡,会有一个“回光返照阶段”。

就是被可达性分析标记为不可达对象时,并不是立即回收内存,而是有一个缓和期,一个对象真正的死亡要经历两次标记。第一次是,进行可达性分析被标记为不可达对象,第二次是检测对象是否执行finalize()方法,如果不用执行,就会被标记第二次。如果需要执行finalize()方法的话,放到名为F-Queue的队列之中后由一条Finalizer线程去执行它们的finalize()方法。finalize()方法是对象逃脱被第二次标记的唯一一次机会,如果对象要在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可。否则收集器将对F-Queue中的对象进行第二次小规模的标记。

3.6 方法区的回收

回收方法区意味着类方法的卸载,比较少见

参考:

深入理解Java虚拟机(第3版),周志明,机械工业出版社

  • 48
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值