回到问题“为何会内存溢出?”。

要回答这个问题又要引出另外一个话题,既什么样的对象GC才会回收?

一、对象存活方式判断方法

在上一篇文章《GC之一--GC 的算法分析、垃圾收集器、内存分配策略介绍》中的“二、对象存活判断”中介绍了,判断对象是否存活一般有两种方式:

  • 引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。
  • 根搜索算法/可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

而且文章中还验证了JVM是通过根搜索算法进行的,而不是通过引用计数方式。

二、java对象的引用

从最强到最弱,不同的引用(可到达性)级别反映了对象的生命周期。见《对象的强、软、弱和虚引用

  • l  Strong Ref(强引用):通常我们编写的代码都是Strong Ref,于此对应的是强可达性,只有去掉强可达,对象才被回收。
  • l  Soft Ref(软引用):对应软可达性,只要有足够的内存,就一直保持对象,直到发现内存吃紧且没有Strong Ref时才回收对象。一般可用来实现缓存,通过java.lang.ref.SoftReference类实现。
  • l  Weak Ref(弱引用):比Soft Ref更弱,当发现不存在Strong Ref时,立刻回收对象而不必等到内存吃紧的时候。通过java.lang.ref.WeakReference和java.util.WeakHashMap类实现。
  • l  Phantom Ref(虚引用):根本不会在内存中保持任何对象,你只能使用Phantom Ref本身。一般用于在进入finalize()方法后进行特殊的清理过程,通过java.lang.ref.PhantomReference实现。

有了上面的种种我相信很容易就能把heap和perm gen撑破了吧,是的利用Strong Ref,存储大量数据,直到heap撑破;利用interned strings(或者class loader加载大量的类)把perm gen撑破。

三、关于shallow size、retained size、Deep size

也有称为Shallow heap、retained heap、deep heap

Shallow(浅) size:就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。在32位系统上,对象头占用8字节,int占用4字节,不管成员变量(对象或数组)是否引用了其他对象(实例)或者赋值为null它始终占用4字节。故此,对于String对象实例来说,它有三个int成员(3*4=12字节)、一个char[]成员(1*4=4字节)以及一个对象头(8字节),总共3*4 +1*4+8=24字节。根据这一原则,对String a=”rosen jiang”来说,实例a的shallow size也是24字节(很多人对此有争议,请看官甄别并留言给我)。

Retained(保留) size:是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。为了更好的理解retained size,不妨看个例子。

把内存中的对象看成下图中的节点,并且对象和对象之间互相引用。这里有一个特殊的节点GC Roots,正解!这就是reference chain的起点。

从obj1入手,上图中蓝色节点代表仅仅只有通过obj1才能直接或间接访问的对象。因为可以通过GC Roots访问,所以左图的obj3不是蓝色节点;而在右图却是蓝色,因为它已经被包含在retained集合内。

所以对于左图,obj1的retained size是obj1、obj2、obj4的shallow size总和;右图的retained size是obj1、obj2、obj3、obj4的shallow size总和。obj2的retained size可以通过相同的方式计算。

Deep(深) size:包含那些对象的大小。深大小与保留大小的区别在于那些存在共享的对象。

如图,Flute Duo对象的深大小包含Michael对象消耗的内存空间,但是保留大小则不包括。(Person Michael是Trio和Flute Duo所共享的)

看堆内存分析工具中展示的都是

GC之二--GC是如何回收时的判断依据、shallow(浅) size、retained(保留) size、Deep(深)size的更多相关文章

  1. gc之六--Minor GC、Major GC、Full GC以及Mixed GC之间的区别

    目录: GC之一--GC 的算法分析.垃圾收集器.内存分配策略介绍 GC之二--GC日志分析(jdk1.8)整理中 GC之三--GC 触发Full GC执行的情况及应对策略 gc之四--Minor G ...

  2. GC之八--GC 触发Full GC执行的情况及应对策略

    目录: GC之一--GC 的算法分析.垃圾收集器.内存分配策略介绍 GC之二--GC日志分析(jdk1.8)整理中 GC之三--GC 触发Full GC执行的情况及应对策略 gc之四--Minor G ...

  3. JVM垃圾回收(二)- Minor GC vs Major GC vs Full GC

    Minor GC vs Major GC vs Full GC 垃圾回收的活动会清理对内存中的不同区域,这些事件一般被称为Minor,Major以及Full GC events.本章我们会讨论这些清理 ...

  4. JVM系列二:GC策略&内存申请、对象衰老

    JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类 现在比较常用的是分代收集(generatio ...

  5. 【转载】JVM系列二:GC策略&内存申请、对象衰老

    JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类 现在比较常用的是分代收集(generatio ...

  6. GC(Garbage Collection)垃圾回收机制

    1.在垃圾回收器中,程序员没有执行权,只有通知它的权利. 2.程序员可以通过System.gc().通知GC运行,但是Java规范并不能保证立刻运行. 3.finalize()方法,是java提供给程 ...

  7. [转]JVM系列二:GC策略&内存申请、对象衰老

    原文地址:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037056.html JVM里的GC(Garbage Collection)的算法有 ...

  8. C# GC Finalizer IDispseable,.Net的垃圾回收机制

    1.GC只能回收堆里的托管资源 2.GC 回收,"代"的概念 .net 托管资源分三代,代数越大 资源的生命周期越长. 0 代 和1代的资源比较少可以比较频率的回收, 回收2代以上 ...

  9. GC(二)CMS

    什么是CMS CMS全称 Concurrent Mark Sweep,是一款并发的.使用标记-清除算法的垃圾回收器, 使用场景 GC过程短暂停,适合对时延要求较高的服务,用户线程不允许长时间的停顿. ...

随机推荐

  1. 用js实现预览待上传的本地图片

    js实现预览待上传的本地图片,代码如下: <form name="form5" id="form5" method="post" ac ...

  2. Oracle PLSQL Demo - 19.管道function[查询整表组成list管道返回]

    create or replace function function_demo RETURN emp PIPELINED as Type ref_cur_emp IS REF CURSOR RETU ...

  3. div,contenteditable编辑器之ctrl+enter换行,enter发送

    //回车发消息 $scope.keyDownSend = function ($event) { var keycode = window.event?$event.keyCode:$event.wh ...

  4. HTML onmousedown 事件属性 关于鼠标按键的问题;

    在项目中遇到一个问题,就是点击任意键关闭弹窗的处理:出现了一个bug:就是在angularjs项目中两个controller之间的事件跳转,使用的ng-show =“iscontext” : 如所示: ...

  5. Makefile初探

    选择一个目录创建一个Makefile文件: 注意第二行的开头需要时TAB建空开,不要用空格 执行make make的时候,无论你创建的是makefile还是Makefile都可以识别 ,不在乎开头的字 ...

  6. 基于jquery的json转table插件jsontotable

    分享一款基于jquery的json转table插件jsontotable.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div class="container ...

  7. plsql 只能识别32位的oracle解决办法

    http://www.cnblogs.com/ymj126/p/3712727.html#undefined

  8. winform文本框不能粘贴、复制和屏蔽右键

    有3个常用方法 1.MouseMove事件中,使选不中 private void textBox3_MouseMove(object sender, MouseEventArgs e) { if (t ...

  9. 802.1q VLAN

    VLAN(Virtual Local Area Network),是一种通过将局域网内的设备逻辑地而不是物理地划分成一个个网段从而实现虚拟工作组的技术. 以一个网络接口为主设备,可以创建多个虚拟网络接 ...

  10. phalcon的CLI应用

    CLI应用是命令行下执行的程序, 可以应用于定时任务,守护进程, 脚本, 公用命令等等. 最小的目录结构:app/config/config.phpapp/tasks/MainTask.phpapp/ ...