版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习!

在堆内存中存放着Java程序中几乎所有的对象实例,堆内存的容量是有限的,Java虚拟机会对堆内存进行管理,回收已经“死去”的对象(即不可能再被任何途径使用的对象),释放内存。垃圾收集器在对堆内存进行回收前,首先要做的第一件事就是确定这些对象中哪些还存活着,哪些已经死去。Java虚拟机是如何判断对象是否可以被回收的呢?

引用计数算法

       引用计数算法的原理是这样的:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;在任何时刻计数器的值为0的对象就是不可能再被使用的,也就是可被回收的对象。

引用计数算法的效率很高,但是主流的JVM并没有选用这种算法来判定可回收对象,因为它有一个致命的缺陷,那就是它无法解决对象之间相互循环引用的的问题,对于循环引用的对象它无法进行回收。

假设有这样一段代码:

public class Object {

    public Object instance;

    public static void main(String[] args) {

        //
Object objectA = new Object();
Object objectB = new Object(); //
objectA.instance = objectB;
objectB.instance = objectA; //
objectA = null;
objectB = null; }

程序启动后,objectA和objectB两个对象被创建并在堆中分配内存,这两个对象都相互持有对方的引用,除此之外,这两个对象再无任何其他引用,实际上这两个对象已经不可能再被访问(引用被置空,无法访问),但是它们因为相互引用着对方,导致它们的引用计数器都不为0,于是引用计数算法无法通知GC收集器回收它们。

实际上,当第1步执行时,两个对象的引用计数器值都为1;当第2步执行时,两个对象的引用计数器都为2;当第3步执行时,二者都清为空值,引用计数器值都变为1。根据引用计数算法的思想,值不为0的对象被认为是存活的,不会被回收;而事实上这两个对象已经不可能再被访问了,应该被回收。

可达性分析算法

       在主流的JVM实现中,都是通过可达性分析算法来判定对象是否存活的。可达性分析算法的基本思想是:通过一系列被称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots对象没有任何引用链相连,就认为GC Roots到这个对象是不可达的,判定此对象为不可用对象,可以被回收。

在上图中,objectA、objectB、objectC是可达的,不会被回收;objectD、objectE虽然有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。

在Java中,可作为GC Roots的对象包括下面几种:

1、虚拟机栈中引用的对象;

2、方法区中类静态属性引用的对象;

3、方法区中常量引用的对象;

4、本地方法栈中Native方法引用的对象。

以上探讨了判定对象是否可回收的两种算法,判定对象是否可回收只是垃圾回收的第一步,接下来还要解决何时回收以及如何回收的问题,在后面的文章中我们来探讨这些问题。

Java虚拟机:如何判定哪些对象可回收?的更多相关文章

  1. (转)《深入理解java虚拟机》学习笔记3——垃圾回收算法

    Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...

  2. 自制Java虚拟机(四)-对象、new、invokespecial

    自制Java虚拟机(四)-对象.new.invokespecial 一.对象的表示 刚开始学Java的时候,图书馆各种教程,书名往往都是“Java面向对象高级编程”,通常作者都会与C++做个比较,列出 ...

  3. 深入理解java虚拟机(三)对象回收判断算法以及死亡过程

    在堆里面存放着Java几乎所有的对象实例,垃圾收集器要进行垃圾回收,要做的第一步便是找出那些对象是需要回收的. 怎么判断对象是否需要回收? 常用的方法有两种. 1.引用计数算法.为每一个对象添加一个引 ...

  4. 《深入理解Java虚拟机》学习笔记之内存回收

    垃圾收集(Garbage Collection,GC)并不是Java语言的半生产物,事实上GC历史远比Java久远,真正使用内存动态分配和垃圾收集技术的语言是诞生于1960年的Lisp语言.经过半个世 ...

  5. 深入理解JAVA虚拟机之JVM性能篇---垃圾回收

    一.基本垃圾回收算法 1. 判断对象是否需要回收的方法(如何判断垃圾): 1) 引用计数(Reference Counting)  对象增加一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回 ...

  6. 《深入理解Java虚拟机》读书笔记2--垃圾回收

    回收哪些内存/对象 引用计数算法 可达性分析算法 finalize()方法 HotSpot实现分析 转载:http://blog.csdn.net/tjiyu/article/details/5398 ...

  7. 《深入理解Java虚拟机》读书笔记3--垃圾回收算法

    转载:http://blog.csdn.net/tjiyu/article/details/53983064 下面先来了解Java虚拟机垃圾回收的几种常见算法:标记-清除算法.复制算法.标记-整理算法 ...

  8. 转!!Java虚拟机堆的内存分配和回收

    Java内存分配和回收,主要就是指java堆的内存分配和回收.java堆一般分为2个大的区域,一块是新生代,一块是老年代.在新生代中又划分了3块区域,一块eden区域,两块surviver区域.一般称 ...

  9. 浅谈Java虚拟机内存中的对象创建,内存布局,访问定位

    参考于 深入理解Java虚拟机 这里介绍HotSpot虚拟机(自带的虚拟机) 1.对象的创建 对于程序员来说,创建对象的方法: User user1 = new User(); User user2 ...

随机推荐

  1. LiteIDE灰调配色方案

    说明 本文写于2017-04-03,使用LiteIDE X31(基于Qt 4.8.5),操作系统为Windows. 使用 LiteIDE下载后解压即可使用.配色方案的所有配置文件都位于liteide/ ...

  2. 关于STM32空闲中断

    有一次做一个东西,为了尽量不占用CPU的处理数据时间,所以就使用DMA接收串口的数据,但是呢问题来了.,,,,,怎么样才能确定接收到了一条完整的数据了,,我们都知道只要打开DMA 那家伙就不停的把接收 ...

  3. poj2069

    poj2069 题意 求一个覆盖所有点的最小球体的半径.即求空间内一点到所有点的距离的最大值最小的点. 分析 模拟退火算法,但这道题竟然不用随机函数就能过了,主要体现了算法的渐近收敛性, 起始点随意取 ...

  4. Java之进程与线程

    一.进程 二.线程 1.定义及特点 1)[定义]线程是一个进程内部的一条执行路径,Java虚拟机允许应用程序并发地运行多个执行路径 是系统独立调度和分派[CPU]的基本单位 2)特点 进程中执行运算的 ...

  5. mysql安装报错

    一: -- MySQL 5.5.22Warning: Bison executable not found in PATH-- Configuring done-- Generating done-- ...

  6. 借用mysql 或者其他数据库 处理MSSQL 2016前处理导入特殊字符

    MSSQL 2016支持了utf8编码的文件,之前处理比较麻烦的bcp 方式导入特殊字符一下子就方便了. 但是之前的版本,处理起来还是有一点麻烦.这次处理使用的数据库版本是sql server 201 ...

  7. python http长连接客户端

    背景: 线上机器,需要过滤access日志,发送给另外一个api 期初是单进程,效率太低,改为多进程发送后,查看日志中偶尔会出现异常错误(忘记截图了...) 总之就是端口不够用了报错 原因: 每一条日 ...

  8. Ajax请求,跨域小坑

    今天在上班的时候,被坐在旁边项目经理叫过去问了一个Ajax请求跨域的问题,一开始没理解清楚也还有对这个没有理解的透,后面被打击的要死. 当时的需求是需要测试一个已发布的api接口,需要在本地写测试程序 ...

  9. Android 创建虚拟机时“提示no system images installed for this target”

    经上网查证,发现原因在于CPU/ABI选项无法选择,并显示“No system images installed for this target”,也就是没有适合的系统镜像,通过与安装好了的ADT-b ...

  10. [0] DDD领域驱动设计(三) 之 聚合(根)、实体、值对象

    1.      聚合根.实体.值对象的区别? 从标识的角度: 聚合根具有全局的唯一标识,而实体只有在聚合内部有唯一的本地标识,值对象没有唯一标识,不存在这个值对象或那个值对象的说法: 从是否只读的角度 ...