简单聊聊java中如何判定一个对象可回收

  背景

  说到java的特性,其中一个最重要的特性便是java通过new在堆中分配给对象的内存,不需要程序员主动去释放,而是由java虚拟机自动的回收。这也是java和C++的主要区别之一;那么虚拟机是如何实现自动回收的呢?它的基本回收算法又是什么呢?  这篇随笔先不介绍这些~ ~,熟话说 饭要一口一口地吃,路要一步一步地走嘛,这篇随笔主要讲解的是回收的前提:如何判断一个对象可以回收。

  

  对java中如何判断一个对象可以回收的一般性认识

  在没有学习《深入理解java虚拟机》之前,对于java中判断一个对象是否可以回收的方法,我自然而然的就想到了通过引用计数的方法就可以做到,我想的是:对象自身有一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时(例如程序离开了引用对象它所在的作用域),计数器值减1;任何时刻计数器为零的对象就是不会再被使用的,内存自动回收时就可以对它进行回收了;

  这种方式又简单,又高效,那为什么主流的java虚拟机没有采用这种方式呢,其中主要的原因是这种方式很难解决对象之间相互循环引用的问题;看下面的简单代码例子:

public class Main {

    public Object instance = null;

    private static final int _1MB = 1024 * 1024;

    //让对象占用一定的内存空间,触发回收    private byte[] bigSize = new byte[2 * _1MB];

    public static void  testGC(){

        Main objA = new Main();

        Main objB = new Main();        //objA中的instance对象引用objB,objB中的instance对象引用objA        objA.instance = objB;        objB.instance = objA;

        //将两个对象都设为null        objA = null;        objB = null;

        System.gc();    }}对于上面的情况,如果java虚拟机采用引用计数的方式进行判断对象是否可以回收,那么objA,和 objB是永远也得不到回收的!

回到题目,那么java虚拟机采用什么方法来进行判断一个对象是否可以被回收呢?可达性分析算法:  正如算法名称说描述的,这个算法的基本思想是:通过一系列称为“GC Root” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Root 没有任何引用链相连接(用图论来说就是从根节点到这个对象节点不可达)时,则证明这个对象是不可用的;如图1-1 所示,对象 5, 6, 7虽然互相有关联,但是它们到GC Root 是不可达的,所以它们将被判定为可回收对象,即这几个对象可以被判定已死亡;

                         如图 1-1:可达性分析算法判定对象是否可回收

  看了上图以后,又会有一个问题,就是如何选取GC Roots:    包括以下下几种对象:    1.虚拟机栈中引用的对象(就是java函数体中的本地变量表)。    2.方法区中类静态属性引用的对象。    3.方法区中常量引用的对象。    4.本地方法栈中JNI(即一般说的Native方法)引用的对象。  

  以上就是我对java内存自动回收部分知识点的一个总结和分享,其中还有很多知识点需要去学习,比如方法区的存储结构是怎样的,存储哪些类型数据信息,虚拟机如何管理这一块内存区域等。希望这次分享能对大家有所启发,有所收获~



时间: 2025-01-02 18:31:53

简单聊聊java中如何判定一个对象可回收的相关文章

简单聊聊java中的BIO、NIO、AIO

BIO(blocking io,同步阻塞) 场景:客户端向服务端发送请求,服务端会为每个客户端建立一个线程来响应,问题来了,如果客户端出现了延时等异常,服务端为客户端建立的线程,就会一直出于等待状态,这个线程就会占用很长时间(因为数据的准备和处理都在这个线程上完成),更糟糕的是,如果有大量并发访问,服务器就会建立大量线程响应,引起服务器资源枯竭. BIO的网络编程模型基本是C/S模型,即两个进程间的通信. 服务端提供IP和监听端口,客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手连

Java中如何序列化一个对象(转)

转自:http://blog.csdn.net/chx10051413/article/details/40784667 http://www.cnblogs.com/baoendemao/p/3804797.html Java 中如何序列化一个对象 我们都知道java 中无法保存一个对象到文本文件中,但是当我们有这种需求的时候,我们可以通过java 的序列化功能把当前对象的一些属性以二进制的形式保存到文件中.当我们需要这个对象的时,只需要从二进制文件中还原为保存前的对象即可.从这里我们可以得到

聊聊Java中的锁

乐观锁与悲观锁 乐观锁 乐观锁就是当一个线程A去修改共享数据B时,线程A假设其它线程都不会去修改B,因此线程A在对共享数据B修改时,不会对共享数据B进行加锁,而是线程A在修改时只需要对共享数据B的旧值或数据版本进行校验,如果校验成功,则修改之,如果校验不成功,则修改失败. 具体在我们Java编程中比较常见的有利用数据库的version(版本号)字段的自增操作来实现乐观锁,具体的细节我们这里不作介绍. 这里我们还介绍另外一个在Java中的具体实现,那就是比较并更新原子性操作.比如说AtomicIn

简单介绍 java 中的几种 "通用方法“

前言 Java中,除了基本的数值类型,其他所有数据类型(包括数组)都是对象. 而Object这个类是所有类的超类,它提供的方法,自然能够使用于它的所有子类(所有非基本数值类型). 本文介绍了Object类的几种经典方法,还算比较常用. Class getClass(),ClassSuperclass () 返回包含对象信息的类对象.此方法将在以后讲反射机制的时候详细讲解. Object clone () 拷贝方法.此方法将在以后专门开篇讲解. int hashCode () 返回对象的哈希值.

Java中内存泄露及垃圾回收机制

3 垃圾回收机制 3.1 什么是垃圾 垃圾,内存中的垃圾,即内存中已无效但又无法自动释放的空间.在Java语言中,没有引用句柄指向的类对象最容易成为垃圾.,产生垃圾的情况有很多,主要有以下3种: (1)       超出对象的引用句柄的作用域时,这个引用句柄引用的对象就变成垃圾. 例: { Person p1 = new Person(); …… } 引用句柄p1的作用域是从定义到“}”处,执行完这对大括号中的所有代码后,产生的Person对象就会变成垃圾,因为引用这个对象的句柄p1已超过其作用

Java并发(10)- 简单聊聊JDK中的七大阻塞队列

引言 JDK中除了上文提到的各种并发容器,还提供了丰富的阻塞队列.阻塞队列统一实现了BlockingQueue接口,BlockingQueue接口在java.util包Queue接口的基础上提供了put(e)以及take()两个阻塞方法.他的主要使用场景就是多线程下的生产者消费者模式,生产者线程通过put(e)方法将生产元素,消费者线程通过take()消费元素.除了阻塞功能,BlockingQueue接口还定义了定时的offer以及poll,以及一次性移除方法drainTo. //插入元素,队列

(3)简单说说java中的异常体系

java异常体系 |--Throwable 实现类描述java的错误和异常 一般交由硬件处理 |--Error(错误)一般不通过代码去处理,一般由硬件保护 |--Exception(异常) |--RuntimeException(运行时异常) |--非运行时异常 多个try-catch语句联用时的顺序 1.顺序执行,从上到下,有一个catch子句匹配之后,后面的自动不在执行 2.如果多个cach内的异常有父子类的关系 一定要,子类异常在上,父类异常在下 自定义异常类型 一般都是提供两个构造参数,

聊聊java中final那点事

1.final是什么 final是一个java关键字,一个修饰符,可用于修饰变量,方法,修饰类. 2.final有什么用 final可以修饰变量时,可以使其值不能改变 final修饰方法时使其不能被重写 final修饰类时,使其不能被继承. 3.final修饰成员变量 fianl最常见的用法时用来修饰成员变量,成员变量分为静态变量与普通变量. 对于final修饰的变量,不是不能被赋值,是其值不能被改变,可以理解成只能赋一次值.可以在定义时赋值,也可以在定义后在另外赋值,但无论何种方式只能被赋值一

简单理解java中timer的schedule和scheduleAtFixedRate方法的区别

timer的schedule和scheduleAtFixedRate方法一般情况下是没什么区别的,只在某个情况出现时会有区别--当前任务没有来得及完成下次任务又交到手上. 我们来举个例子: 暑假到了老师给schedule和scheduleAtFixedRate两个同学布置作业. 老师要求学生暑假每天写2页,30天后完成作业. 这两个学生每天按时完成作业,直到第10天,出了意外,两个学生出去旅游花了5天时间,这5天时间里两个人都没有做作业.任务被拖延了. 这时候两个学生采取的策略就不同了: sch