JVM的垃圾回收

看了周志明的《深入理解Java虚拟机》,重新理解了JVM的垃圾回收机制。建议没看过原书的先去读一下原书,一在网上看各种博文大多数都是从那本书中出来的,而且很多都只是截取了一部分,并不能很好的表达JVM的意思。我原先就是背八股,背的云里雾里的,这次看过原文豁然开朗。强烈安利~~~

首先要理解JVM的内存划分:方法区、程序计数器、虚拟机栈、本地方法栈、堆。

垃圾回收主要是指的堆的回收,但是也包括方法区。只不过方法区内垃圾回收的效率和结果不尽如人意,堆中垃圾回收一次可以收回70%—95%,而方法区远远达不到这个。

垃圾回收的时间肯定知道,没内存了或者即将要没没存了,就进行一次垃圾回收。但是如何判断是不是垃圾,JVM使用的是可达性算法,还有一种方法叫引用计数法。

引用计数法:就是一个对象有一个统计被引用的次数,新增一个引用数量加一,释放一个引用数量就减一,当引用数量为0的时候就是垃圾,可以被回收。好处的简单,就是数量的加减,坏处的可能出现相互应用的情况,导致内存泄漏(假设有两个对象A、B, 在A中引用B,在B中引用A,然后AB都不使用,但是AB的计数都不为0无法释放)。

可达性分析法:主流的商用语言用的都是可达性分析法。可达性分析法源头是GC Roots,从起始点开始搜索,走过的路径叫做引用链。当一个对象没有引用链经过,就被判定为垃圾。能作为GC Roots的对象有四种:

虚拟机栈(本地变量表)中引用的对象
方法区中静态类型属性引用的对象
方法区常量引用的对象
本地方法栈中引用的对象

JDK还对引用进行了区分,分别是强引用、软引用、弱引用、虚引用。但是目前我完全不知道这么分有啥作用,或者说除了强引用其他三种我都还没用过。

强引用:Object A = new Object() 类似这种,是程序中最常见的。只要强引用还在,就不会被回收。
软引用:有用但并非必须的对象。判断不可达之后,也不会直接回收,等到内存不够了才清理他们。
弱引用:非必需的对象。遇到之后就直接回收,不等内存不够用。
虚引用:任何时候回收都可以。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

JVM判断某对象不可达,该对象可以被清除的时候,也不是“非死不可”。个人理解是每一个对象可以有一个免死金牌,只能用一次,也就是finalize()方法。两次标记:当判断一个对象不可达之后,该对象会被进行第一次标记,同时进行一次筛选(该对象是否用finalize()方法且该方法一次也没有执行),如果有finalize()且一次也没执行,就将对象放进F-Queue队列中。JVM虚拟机会自动建立一个低优先级的线程(Finalizer)去执行访问这个队列,执行每个对象的finalize()方法。如果这个对象在finalize()中让此对象又关联到GC Roots,即变的可达了。那么将不会被回收,如果未能关联GC Roots则被回收。

需要注意的如果没有finalize()方法,或者说已经执行过一次了,那么会直接清除。死里逃生只能是上一段中最后变可达的对象,finalize()函数的作用也可以是在对象回收之前执行特定的动作(比如释放连接社么的),但是也可以用try/catch/finally语句执行类似的功能。而且Finalizer线程是尝试着去执行对象的finalize,并不是一定会执行完,万一某个对象的finaliz陷入死循环或者出bug,那其他要回收的怎么办?回收线程还怎么处理其他不可达对象。但是书里没说具体怎么判断,猜测应该是有一个判断时间,时间一到还没有结束直接清理。

上面说的都是堆(对象都是在堆中的),而方法区的回收主要分为类的回收和废弃常量回收。根据JVM的运行时数据区设置,方法区中包含运行时常量池。废弃常量和对象处理方法类似,没人引用了就可以回收了。而类的回收则比较麻烦,类必须满足以下三条才能算是无用的类:

该类所有实例都已经被回收,也就是Java中不存在任何该类的实例。
加载该类的ClassLoader已经被回收。
该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的对象。

也好理解,第一条程序中还有类的实例,肯定不能回收,不然对象的getClass()函数去找谁。第三条也是同理。

不过就算是满足了上面的,是一个无用的类,也不一定会被回收。是否对类回收,还得看虚拟机的设置。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值