简单聊聊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内存自动回收部分知识点的一个总结和分享,其中还有很多知识点需要去学习,比如方法区的存储结构是怎样的,存储哪些类型数据信息,虚拟机如何管理这一块内存区域等。
希望这次分享能对大家有所启发,有所收获~
简单聊聊java中如何判定一个对象可回收的更多相关文章
- 简单聊聊java中的final关键字
简单聊聊java中的final关键字 日常代码中,final关键字也算常用的.其主要应用在三个方面: 1)修饰类(暂时见过,但是还没用过); 2)修饰方法(见过,没写过); 3)修饰数据. 那么,我们 ...
- 简单聊聊CSS中的3D技术之“立方体”
简单聊聊CSS中的3D技术之“立方体” 大家好,我是今天的男一号,我叫小博主. 今天来聊一下我在前端“逆战班”学习中遇到的颇为有趣的3D知识.前端学习3周,见识稀疏,在下面的分享中如有不对的地方请大家 ...
- Java中如何序列化一个对象(转)
转自:http://blog.csdn.net/chx10051413/article/details/40784667 http://www.cnblogs.com/baoendemao/p/380 ...
- Java中内存泄露及垃圾回收机制
转自:http://blog.sina.com.cn/s/blog_538b279a0100098d.html 写的相当不错滴...................... 摘 要 Java语言中,内 ...
- Java基础-Java中的内存分配与回收机制
Java基础-Java中的内存分配与回收机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. 二.
- 聊聊 Java 中日期的几种常见操作 —— 取值、转换、加减、比较
Java 的开发过程中免不了与 Date 类型纠缠,准备总结一下项目经常使用的日期相关操作,JDK 版本 1.7,如果能够帮助大家节约那么几分钟起身活动一下,去泡杯咖啡,便是极好的,嘿嘿.当然,我只提 ...
- 并发王者课 - 青铜 2:峡谷笔记 - 简单认识Java中的线程
在前面的<兵分三路:如何创建多线程>文章中,我们已经通过Thread和Runnable直观地了解如何在Java中创建一个线程,相信你已经有了一定的体感.在本篇文章中,我们将基于前面的示例代 ...
- 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接
长久以来,我们被教导字符串的连接最好用StringBuffer.StringBuilder,但是我们却不知道这两者之间的区别.跟字符串相关的一些方法中总是有CharSequence.StringBuf ...
- Java中输入判定的错误和纠正
在编程过程中,很多技术人员看重程序的简洁性,效率性和包容性.其中最容易问到的就是假如输入数据不符合要求时的程序处理,这也是很多公司的机试题中应聘人员写出了符合功能要求的程序却并未通过面试的原因.下面是 ...
随机推荐
- java 学习笔记——类之间的关系之封装、继承与多态的详解
封装 一个封装的简单例子 封装就是把对象的属性(状态)和方法(行为)结合在一起,并尽可能隐蔽对象的内部细节,成为一个不可分割的独立单位(即对象),对外形成一个边界,只保留有限的对外接口使之与外部发生联 ...
- VB.NET 中 ComboBox 如何清除选项--- 使用Dataset 赋值 DataSource 的时候
如题: 在 使用Dataset 赋值 DataSource 的时候,网络上很多都是:ComboBox2.DataSource = Null 然并卵,很高兴告诉大家:Null 在VB.NET中是没用的: ...
- Ubuntu Docker 版本的更新与安装
突然发现自己的docker 版本特别的低,目前是1.9.1 属于古董级别的了,想更新一下最新版本,这样最新的一下命令就可以被支持.研究了半天都没有更新成功,更新后的版本始终都是1.9.1 :蒙圈了,找 ...
- Java中Math.round()函数
Math.round(11.5) = 12; Math.round(-11.5) = -11; Math.round()函数是求某个数的整数部分,且四舍五入.
- Java—Day5课堂练习
package com.lovo.classes;import java.util.Scanner;public class day5Test { public static void main ...
- win10 uwp 绘图 Line 控件使用
本文主要讲一个在绘图中,我们会有一个基础的控件,Line.控件的基本使用和他能做出的我们很多时候需要的界面. 虽然是一个简单控件,但是可以做出很诡异的很好看的UI. 首先,我们要知道,Line就是画直 ...
- ST40 自制 JTAG 适配器
// 文章首发于 https://zhuanlan.zhihu.com/p/28762429 // 但是不知道为什么搜索引擎还没有收录,便在博客再次发布. 0. 引言 意法半导体生产的 SH4 架构的 ...
- Django(二)
QuerySet与惰性机制: 所谓惰性机制:Publisher.objects.all()或者所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个Que ...
- Windows Server 2008通过计划任务定时执行bat文件
前段时间在Windows Server 2008安装了一套基于MySQL数据库的软件,处于数据安全的考虑,希望每天能够自动进行数据库备份.我在别人脚本的基础上自己写了一个数据库备份的bat脚本,双击该 ...
- 【转】缓存淘汰算法系列之1——LRU类
原文地址:http://www.360doc.com/content/13/0805/15/13247663_304901967.shtml 参考地址(一系列关于缓存的,后面几篇也都在这里有):htt ...