首页 技术 正文
技术 2022年11月18日
0 收藏 496 点赞 5,038 浏览 1438 个字

  背景

  说到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 是不可达的,所以它们将被判定为可回收对象,即这几个对象可以被判定已死亡;简单聊聊java中如何判定一个对象可回收
简单聊聊java中如何判定一个对象可回收
                         
如图 1-1:可达性分析算法判定对象是否可回收  看了上图以后,又会有一个问题,就是如何选取GC Roots:
    包括以下下几种对象:
    1.虚拟机栈中引用的对象(就是java函数体中的本地变量表)。
    2.方法区中类静态属性引用的对象。
    3.方法区中常量引用的对象。
    4.本地方法栈中JNI(即一般说的Native方法)引用的对象。
    以上就是我对java内存自动回收部分知识点的一个总结和分享,其中还有很多知识点需要去学习,比如方法区的存储结构是怎样的,存储哪些类型数据信息,虚拟机如何管理这一块内存区域等。
希望这次分享能对大家有所启发,有所收获~
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,105
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,582
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,429
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,836
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,919