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





  • 相关阅读:
    TSP-UK49687
    维度建模的基本原则
    差分约束系统
    随机过程初步
    随机过程——维纳过程
    Xilinx FPGA复位信号设计
    10 Row Abacus
    Python
    FX2LP与FPGA的简单批量回环
    DFT公式的一个简单示例
  • 原文地址:https://www.cnblogs.com/Qinmp-Blog/p/5693318.html
Copyright © 2020-2023  润新知