商业网站域名后缀,如何做免费网站制作,wordpress多级筛选,公司网站模版 dedecms1、前言《JVM学习.01 内存模型》篇讲述了JVM的内存布局#xff0c;其中每个区域是作用#xff0c;以及创建实例对象的时候内存区域的工作流程。上文还讲到了关于对象存货后#xff0c;会被回收清理的过程。今天这里就着重讲一下对象实例是如何被清理回收的#xff0c;以及清…1、前言《JVM学习.01 内存模型》篇讲述了JVM的内存布局其中每个区域是作用以及创建实例对象的时候内存区域的工作流程。上文还讲到了关于对象存货后会被回收清理的过程。今天这里就着重讲一下对象实例是如何被清理回收的以及清理回收的几种算法。2、再谈引用JDK1.2版本之后对引用的概念进行了扩充分为强引用软引用弱引用虚引用。这4种引用关系强度依次减弱。2.1、Strongly Reference 强引用强应用是最传统的”引用“定义。这种引用关系无论任何情况包括OOM异常只要强引用关系还存在GC就不会回收掉被引用对象。声明方式Object object new Object();2.2、Soft Reference 软引用一种相对强引用弱化了一些的引用。比如高速缓存就可以用到软引用。当内存足够时就保留不够时就回收。其中当系统内存充足的时候不会被回收当系统内存不足的时会将这些对象列进回收范围之中进行第二次回收如果还是内存不足才会抛出内存溢出异常。声明方式 SoftReference softReference new SoftReference(obj);2.3、Weak Reference 弱引用弱引用的强度比软引用更弱一些。被弱引用关联的对象生命周期只能到下一次GC。当GC开始工作无论当前的内存是否够用都会会受到被弱引用关联的对象。声明方式WeakReference weakReference new WeakReference(obj);2.4、Phantom Reference 虚引用虚引用是最弱的一种引用关系。一个对象是否有虚引用的存在完全不会对该对象的生存时间构成影响也无法通过虚引用来取得一个对象实例。虚引用的作用主要是用来跟踪对象被垃圾回收的状态。设值虚引用关联的唯一目的就是在这个对象被回收的时候收到一个系统通知或是后续添加进一步的操作处理。声明方式PhantomReference phantomReference new PhantomReference(obj rq);2.5、各引用小结强引用对象不会被回收出现OOM软引用内存不够时才回收二次清理弱引用只要GC就回收虚引用用于检测对象的GC状态3、如何判断对象“存活”3.1、引用计数算法在JVM中专门开辟一块额外的内存空间专门用来对实例引用进行技数。一个对象如果在JVM中有被别人引用关联或持有则计数器1反之则-1。任何时刻只要计数器为0的对象没有任何指针对其引用那么他就是不是存活需要被清理。这种的技数方式虽然原理简单效率也很高且有不错的案例使用。但是依然存在弊端。看一段代码public class GcReferenceCount {public void testGC(){GcObject gcObj1 new GcObject(); GcObject gcObj2 new GcObject(); gcObj1.gcObj gcObj2;gcObj2.gcObj gcObj1;gcObj1 null;gcObj2 null;// 假设这里发生了gcSystem.gc();}
}class GcObject {GcObject gcObj;
}上述代码gcObj1和gcObj2互为引用。就算当gcObj1 nullgcObj null那么计数器永远不可能为0意味着永远不可能被回收。3.2、可达性分析算法通过一系列被称为“GC Roots”的根对象作为起始节点集从这些节点开始根据引用关系向下搜索搜索过程所走的路径称为“引用链”。如果某个对象到GC Roots间都没有任何的引用链关联或者说到GC Roots对象不可达的则证明此对象是内存垃圾。通过这种方式可以规避引用计数算法存在的相互指向的问题。也是目前GC中默认的分析标记算法。网上借来的图3.3、并发的可达性分析这里的并发指的是用户线程和GC线程同时工作。3.2中提到的可达性分析算法用来断定对象是否存活。理论上要求标记的全过程都基于一个保障一致性的快照中才能进行假设一边在进行链路搜索一边用户线程又在更改对象引用指向那么起初搜索过的路径就会存在歧义。且往往需要标记的对象又是大多数这时候随着堆变大而等比例的增加STW停顿时间那么也将直接影响整个系统。为了解决或降低用户线程的停顿即要搞为什么必须要在一个能保证一致性的快照中才能进行。引入了”三色标记“算法作为工具来辅助推导。这里将对象按照”是否访问过“分成三种颜色白色该对象没有被GC访问过。黑色该对象被GC访问过他是安全存活的且这个对象所有引用都被扫描过。灰色该对象被GC访问过但这个对象至少存在一个引用还没被扫描过。关于并发可达性分析算法可能存在两个问题1、原本消亡的对象被错误标记为存活这个是可以容忍的。只不过产生了一点浮动垃圾而已等待下次回收就可以了。2、原本存活的对象被错误标记为消亡这个可能会导致系统的致命错误。关于并发出现”对象消失“问题示意图同时满足两个条件时就会出现”对象消失“的问题1、赋值器插入一条或多条从黑色对象到白色对象的新引用2、赋值器删除了全部从灰色对象到该白色对象的直接或间接引用解决方式1、增量更新。破坏第一个条件。当黑色对象插入新的指向白色对象的引用时把这个新的引用记录下来等并发标记结束之后再扫描一次这个记录。比如用一个队列记录下来。可以理解为黑色对象一旦新插入白色对象的引用之后它就变回灰色对象了。2、原始快照。破坏第二个条件。当灰色对象要删除指向白色对象的引用时就把这个要删除的引用记录下来等并发标记结束之后再以这个记录里的灰色对象为根重新扫描一次。4、内存回收策略4.1、标记 - 清除算法标记标记处所有需要回收的对象也可以反过来标记存活的对象。清除在标记完成后统一回收所有被标记的对象如果标记的是需要被回收的对象的话否则反之。网上借的图主要缺点1、执行效率不稳定。如果Java堆中包含大量对象且其中大部分是需要被回收的。必须进行大量的标记动作导致执行效率会随着对象数量增加而降低2、空间碎片化。标记清除后会产生大量不连续的内存碎片。空间碎片太多会导致后面大对象分配时无法找到足够的连续空间。4.2、标记 - 复制算法将内存分为大小相等的两块空间每次只使用其中一块。标记标记处所有需要回收的对象也可以反过来标记存活的对象。复制当其中一块的内存不足时将存活的对象复制到另一块内存中。然后把这块的对象清理。网上借的图主要缺点1、空间利用率低。以空间换时间的做法造成空间浪费其间始终有一块内存没有被使用。2、效率问题。如果对象有大量都是存活的那么复制的对象很多效率自然也会低下。主要优点适合大量对象都是短生命周期的。一次性收集后存活对象很少的情况。同时也避免了空间碎片的问题。4.3、标记 - 整理算法结合了标记清除和标记复制的优缺点。标记标记处所有需要回收的对象也可以反过来标记存活的对象。整理当被标记对象需要被清理时对存活的对象不进行复制而是统一向一端移动然后清理掉端边界外部的内存空间。网上借的图主要缺点1、效率问题。每次存活对象的移动都带来大量的内存重新寻址的计算量 执行效率较低。甚至低于复制算法。主要优点不会造成空间碎片和空间浪费问题。4.4、分代收集原则到目前为止大多数的回收器都遵循分代垃圾收集原则。新生代以标记复制算法居多。大部分对象生命周期较短采用复制算法可以避免一定的空间碎片问题且效率比较高老年代标记清除或标记整理算法。因为对象的存活时间比较长。5、小结到这里讲述了JVM中的内存回收以及引用如何被垃圾收集器回收的一些算法。对JVM的内存使用更加了解。其实JVM相关内容看过很多次但是从来没有过系统性的整理大部分都停留在脑子中。第一次尝试整理这些内容一方面可以加深自己的印象另一方面通过搜索其他的参考资料可以发现很多以前忽略的地方。或许这个就是写技术博客的魅力吧。虽然千篇一律但都是自己手敲原创。respect参考资料《深入理解Java虚拟机》第三版