博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第三章:垃圾回收器:垃圾回收器的两种算法
阅读量:7124 次
发布时间:2019-06-28

本文共 1799 字,大约阅读时间需要 5 分钟。

垃圾回收需要考虑三个问题:
哪些内存需要回收?
什么时候回收?
如何回收?
 
JVM中程序计数器、虚拟机栈、本地方法三个区域随线程而生,随线程而死,这三个区域的内存分配和回收都具有确定性,在这个几个区域不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就随着回收了。
而Java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的不同分支需要的内存也可能不一样,我们只能在运行期间才能知道会创建哪些对象,这部分内存的分配和回收时动态的,垃圾收集器主要关注的是这部分区域。
 
在Java堆中存放着java世界几乎所有的对象实例,垃圾回收器在对堆进行回收前,首要意见事就是确定哪些还存活着,哪些已经死去(即再不可能被任何途径使用的对象)
  • 引用计数器算法
给对象中添加一个引用计数器,每当有一个地方引用它时,计时器就加1,当引用失效时就减1,任何时刻计时器为0的对象就是不可能再被使用的。
引用计数器的优点:实现简单;
缺点:无法解决互相引用的问题
类似A实例引用B实例,B实例引用A实例,这种情况A、B两个实例的引用计数器都不为0,永远无法回收。
  • 可达性分析算法
这个算法的思路就是通过一系列称为GC Root的对象作为起始点,从这些起始点开始向下搜索,搜索路径所走过的路径叫做引用链,当一个对象到GC root没有任何引用链相连时,则证明此对象时不可能再被使用的,可以将这些对象定义为可回收的对象。
在java语言中,可作为GC Roots的对象包括以下四种:
虚拟机栈(栈帧中的本地变量表)中的引用对象
方法区中类静态属性引用的对象
方法区中常量引用对象
苯菲方法栈中JNI(即一般说的Native方法)引用的对象
 
无论是引用计数器还是可达性分析算法都是与对象是否存在活着的引用有关。
JDK1.2之前java中的引用的定义为如果reference雷丁的数据中存储的数值代表的是另一块内存的起始地址,就称为这块内存代表着一个引用。
JDK1.2之后,Java对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用、虚引用四种:
  • 强引用:可以理解为Object ob = new Object(),这种代码中普遍存在的引用,只要强引用还在,垃圾回收器就不会进行回收;
  • 软引用:用来描述一些还有用但是并非必需的对象,对于软引用关联的队盎,在系统将要发生内存溢出异常前,将会把这些对象列进回收范围值周进行二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。
  • 弱引用:用来描述非必要的对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象之鞥呢存活到下一次垃圾收集发生之前,当垃圾回收器工作时,无论当前的内存是否足够,都会回收掉被弱引用关联的对象。
  • 虚引用:它是最弱额的一种引用关系,一个对象是否是虚引用完全不会对其生命时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
 
即使可达性算法中不可达的对象,也并非时“非死不可”,这时候他们这哪是处于“缓刑”节点,要真正宣告一个对象死亡,至少要经理两次标记过程:如果对象在进行可达性分析后发现没有雨GC Roots相连的引用链,那么它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize方法。当对象没有覆盖finalize方法或者finalize方法已经被虚拟机调用过了,虚拟机将这种情况视为“没有必要执行”。
如果一个对象被判定为有必要执行finalize方法,那么这个对象将会放置在一个叫做F-Queue的队列中,并在稍后有一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它,这里所谓的执行是指虚拟机会触发这个方法,当时并不会承诺登台它运行结束,这样做的原因是防止F-Queue队列中其他对象永远处于等待甚至发生了死循环,从而影响整个内存回收奔溃。
finalize是对象逃脱死亡的最后一次机会。如果在进行第二次标记时,对象要在finalize中成功拯救自己,只要重新与引用链上的任何一个对象建立关联即可。
需要注意的一点是:任何一个对象的finalize方法都只会被系统自动调用一次。

转载于:https://www.cnblogs.com/use-D/p/10633962.html

你可能感兴趣的文章
win7 下安装 iis7.5+php5.3的配置方法(图文)
查看>>
SQL语句学习之路10
查看>>
[用事实说明两个凡是]一个mysql莫名锁表的问题
查看>>
ubuntu设置静态IP
查看>>
hql select from与from 的区别
查看>>
wxPython之Socket客户端
查看>>
linux系统目录结构详解(简单易懂)
查看>>
学习《Effective C++》
查看>>
CS224n笔记9 机器翻译和高级LSTM及GRU
查看>>
KVM虚拟机
查看>>
GdiPlus[57]: 图像(九) IGPBitmap 特有的属性与方法
查看>>
Windows 多媒体函数(winmm.dll 中的函数)汇总
查看>>
关于 Delphi 中流的使用(4) 遍历读取流中的所有数据
查看>>
使用 IntraWeb (4) - 页面布局之 TIWRegion
查看>>
域控的升级及客户端加入域
查看>>
【Java每日一题】20161129
查看>>
[译文]greenlet:轻量级并发程序
查看>>
五分钟学会HTML
查看>>
请求Servlet 得到 Request 里所有对象
查看>>
volatile 和 synchronized 的比较
查看>>