文档章节

JVM对循环引用对象的回收

千面人
 千面人
发布于 2017/03/23 13:26
字数 387
阅读 182
收藏 0

判断对象是否存活的算法中,引用计数算法广为人知。但是它有个缺点,就是很难解决对象间的相互循环引用。我曾一度误以为jvm也是采用这个算法,只是不知道,jvm是怎么回收循环引用对象的,以为在引用计数上又叠加了其他算法。然而事实是,java用的是可达性分析算法。被自己蠢哭!

写一段有循环引用的代码。(参考《深入理解JAVA虚拟机》--周志明)

$ cat ReferenceCountingGC.java
public class ReferenceCountingGC{
        public Object instance = null;
        private static final int _1MB = 1024*1024;
        private byte[] bigSize = new byte[2*_1MB];
        public static void main(String[] args){
                ReferenceCountingGC objA = new ReferenceCountingGC();
                ReferenceCountingGC objB = new ReferenceCountingGC();
                objA.instance = objB;
                objB.instance = objA;
                objA = null;
                objB = null;

                System.gc();
        }
}

编译,JDK环境1.8 虚拟机HotSpot 64位:

$ java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
$ javac ReferenceCountingGC.java

运行并查看GC日志:

$ java -XX:+PrintGCDetails ReferenceCountingGC
[Full GC (System.gc()) [Tenured: 0K->255K(344064K), 0.0021897 secs] 7557K->255K(498944K), [Metaspace: 2478K->2478K(1056768K)], 0.0026702 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
 def new generation   total 154944K, used 1378K [0x00000005c9400000, 0x00000005d3c10000, 0x0000000670d50000)
  eden space 137792K,   1% used [0x00000005c9400000, 0x00000005c9558920, 0x00000005d1a90000)
  from space 17152K,   0% used [0x00000005d1a90000, 0x00000005d1a90000, 0x00000005d2b50000)
  to   space 17152K,   0% used [0x00000005d2b50000, 0x00000005d2b50000, 0x00000005d3c10000)
 tenured generation   total 344064K, used 255K [0x0000000670d50000, 0x0000000685d50000, 0x00000007c0000000)
   the space 344064K,   0% used [0x0000000670d50000, 0x0000000670d8ffd0, 0x0000000670d90000, 0x0000000685d50000)
 Metaspace       used 2485K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 267K, capacity 386K, committed 512K, reserved 1048576K

从gc日志可以看到内存的回收: 

[Full GC (System.gc()) [Tenured: 0K->255K(344064K), 0.0021897 secs] 7557K->255K(498944K), [Metaspace: 2478K->2478K(1056768K)], 0.0026702 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 

 

© 著作权归作者所有

千面人
粉丝 18
博文 48
码字总数 24904
作品 0
杭州
高级程序员
私信 提问
好程序员Java教程分享之jvm篇

好程序员java教程分享之jvm篇,在前面的文章中,介绍了JVM内存模型分为:堆区、虚拟机栈、方法区、本地方法区和程序计数器,其中堆区是JVM中最大的一块内存区域,在Java中的所有对象实例都保...

好程序员IT
06/11
59
0
Java的初始化机制、垃圾回收机制和内存分配机制

刚才在网上看到一篇关于java初始化、垃圾回收机制和内存分配机制的文章,感觉不错,就拿来转发了,以后有空可以再看看,应该会有新的认识和新的收获。 文章: 2.1初始化顺序: [java]view p...

java_T
2013/03/17
433
0
JVM系列第8讲:JVM 垃圾回收机制

在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由《Java 虚拟机规范》指定的,每个 Java 虚拟机可能都有不同的实现。其实涉及到 Java 虚拟机的内存,就不得不谈到 Ja...

陈树义
2018/11/21
0
0
12-《深度拆解JVM》之垃圾回收(上)

一、问题引入 你应该听说过这么一句话:免费的其实是最贵的。 Java 虚拟机的自动内存管理,将原本需要由开发人员手动回收的内存,交给垃圾回收器来自动回收。不过既然是自动机制,肯定没法做...

飞鱼说编程
2018/10/26
31
0
深入探讨 java.lang.ref 包

Java.lang.ref 是 Java 类库中比较特殊的一个包,它提供了与 Java 垃圾回收器密切相关的引用类。这些引用类对象可以指向其它对象,但它们不同于一般的引用,因为它们的存在并不防碍 Java 垃圾...

红薯
2011/04/29
1K
6

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
6
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部