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

【java进阶】java虚拟机垃圾回收详解(一)--判断对象已死

2018-08-30 11:30 429 查看

说起垃圾回收,应该思考三个问题。

1.那些区域需要回收?

2.什么时候回收?

3.怎么回收?

参考上一篇文章谈到的java虚拟机内存区域划分,我们知道,jvm内存区域中虚拟机栈,本地方法栈,程序计数器都属于线程私有的。这三个区域随线程生而生,随线程死而灭。栈中的栈帧随着方法的进入和推出有条不紊的进行着入栈和出栈操作。每一个栈帧分配多少内存基本上在类结构确定下来的时候就已知。而堆和方法区属于共享的区域。是需要垃圾回收的区域。

GC收集死去的对象,那么java虚拟机怎么判断一个对象死了吗?

1.引用计数法

给对象中添加一个引用计数器。每当有一个地方引用这个对象,引用计数器自动加1,当引用失效,引用计数器自动减1,当引用计数器值为0时,表示对象已经死了。主流的java虚拟机并没有用引用计数法管理内存。主要是因为无法解决对象循环引用的问题。例如: a = b; b=a;其余地方不再引用a,b。显然这两个对象都已经死了。可是他们的引用计数器还是1。

2.可达性分析算法。

可达性算法是通过一系列GCRoots的对象作为开始点,从GCRoots开始向下搜索。搜索走过的路径称为引用链。如果一个对象到GCRoot没有引用链链接。说明这个对象不可达,对象已死。

GC Roots包括以下几种:

1).虚拟机栈(栈帧中的本地变量)中引用的对象。

2).方法区中静态属性引用的变量。

3).方法区中常量的引用对象。

4).本地方法栈中JNI引用的对象。

大白话说法就是:jvm通过可达性分析算法,从栈帧中的本地变量,方法区中的静态属性,常量以及本地方法栈中JNI引用去搜索引用链。如果可以搜索到,则说明这个对象或者,如果搜索不到。说明这个对象已死了。可以回收了。

判断对象是否活着,主要看这个对象是否存在引用。咱们再来谈谈引用。

传统的引用:如果一个reference类型的数据中存储的数值代表的是另一块内存的起始地址。则说明这块内存有引用。一个对象只有被引用和没有被引用两种状态。对于一些“食之无味,弃之可惜”的对象无法描述。我们希望存在这种对象,如果内存足够则保留,如果内存紧张则抛弃这些对象。

jdk1.2之后,将引用分为强引用,软引用,弱引用,幽灵引用4个等级。

1).强引用:类似“Object a = new Object();”这类的引用,如果强引用存在,对象永远不会被收回。

2).软引用:通过SoftReference类来实现。在内存即将溢出之前,将这些对象进行第二次回收。

3).弱引用:WeakReference类实现。对象只能生存到写一次垃圾回收之前。

4).幽灵引用:通过Phantomreference实现。一个对象设置虚拟引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

 

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: