简单聊聊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中输入判定的错误和纠正
在编程过程中,很多技术人员看重程序的简洁性,效率性和包容性.其中最容易问到的就是假如输入数据不符合要求时的程序处理,这也是很多公司的机试题中应聘人员写出了符合功能要求的程序却并未通过面试的原因.下面是 ...
随机推荐
- 郑厂长系列故事——排兵布阵 hdu4539(状态压缩DP)
郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)To ...
- Nginx详细安装部署教程
一.Nginx简介 Nginx是一个web服务器也可以用来做负载均衡及反向代理使用,目前使用最多的就是负载均衡,具体简介我就不介绍了百度一下有很多,下面直接进入安装步骤 二.Nginx安装 1.下载N ...
- Python3常用学习网站总结(随时更新)
Python资源大全 http://python.jobbole.com/84464/ https://github.com/jobbole/awesome-python-cn scrapy: h ...
- 在C#中实现串口通信的方法
通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围.可以访问h ...
- Interface request structure used for socket ioctl's
1. 结构体定义 /* * Interface request structure used for socket * ioctl's. All interface ioctl's must have ...
- iOS开发必不可少的76个工具
如果你去到一位熟练的木匠的工作室,你总是能发现他/她有一堆工具来完成不同的任务. 软件开发同样如此.你可以从软件开发者如何使用工具中看出他水准如何.有经验的开发者精于使用工具.对你目前所使用的工具不断 ...
- WPF 圖表控件 MetroChart
Torsten Mandelkow MetroChart包括以下: ColumnChart(ClusteredColumnChart,StackedColumnChart,StackedColumnC ...
- win10 uwp iot
这篇文章主要译: https://msdn.microsoft.com/magazine/mt694090 有很多都是胡说,随便喷,但我不会理. https://blogs.msdn.microsof ...
- C#编译器和CLI的安装
为了完成C#程序编译和运行,需要安装代码对应版本的编译器和CLI(公共语言框架)平台. (部分内容摘自<C#本质论>) 针对主流的CLI平台(Microsoft .NET),有两种安装方案 ...
- (转)Java Socket编程
原文出自:http://www.cnblogs.com/rocomp/p/4790340.html Socket是网络驱动层提供给应用程序编程接口和一种机制.可以把Socket比喻成一个港口码头,应用 ...