您的位置:首页 > 编程语言 > Java开发

Java垃圾收集——对象已死?

2016-11-03 19:43 453 查看

Java垃圾收集——对象已死?

Java虚拟机的内存区域中,程序计数器、虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭;栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这三个区域的内存分配和回收都具有确定性。垃圾回收重点关注的是堆和方法区部分的内存。

一、引用计数算法

給对象添加一个引用计数器,但有一个地方引用它时,计数器加1,引用失效时,减1,任何引用计数为0的随想都是可能被回收的。

实现简单,判定效率也高,但是如果有两个对象互相引用时,将无法回收。

二、根搜索算法

通过一系列的名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连,则证明该对象是不可用的。

以下可作为GC Roots:

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

* 方法区中的类静态属性引用的对象

* 方法区中的常量引用的对象

* 本地方法栈中JNI的引用的对象

三、引用分类

* 强引用:Object o = new Object()这种引用,只要强引用存在,垃圾收集器就不会回收

* 软引用:一些还可用,但并非必需的对象。在系统将要发生内存溢出异常之前,将会把这些对象列入回收范围。通过SoftReference实现。

* 弱引用:非必须对象。比软引用更弱。只能生存到下一次垃圾回收之前,通过WeakReference实现。

* 虚引用:幽灵引用,最弱的一种引用。一个对象是否有虚引用,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用的唯一目的就是希望能在对象在被垃圾收集时得到一个系统通知。通过PhantomReference实现。

四、二次标记与finalize()方法

在根搜索算法中不可达的对象,将会被第一次标记并根据是否实现了finalize方法和是否调用过finalize筛选,如果这个对象认为有必要执行finalize方法,就会放入一个F-Queue的队列中执行,稍后GC将对F-Queue中的对象进行二次标记,如果对象在finalize中拯救了自己(只要重新与引用链上任何对象建立关联就行),那么二次标记后他将移出“即将回收”队列,如果没有,就离死亡不远了。不过finalize只会执行一次,下次回收时就无法拯救了。(不建议实现finalize方法)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息