网站的做网站公司哪家好,佛山有几个区,深圳市住建设局网站,墙绘网站建设前言不同于C程序员必须自己完成内存的分配、使用和释放#xff0c;JAVA语言提供了垃圾回收机制(GC#xff0c;Garbage Collection)#xff0c;所以JAVA程序员仅需要负责分配和使用内存即可#xff0c;而释放内存则由GC负责。这样程序员就从讨厌的内存管理的工作中脱身了。本…前言不同于C程序员必须自己完成内存的分配、使用和释放JAVA语言提供了垃圾回收机制(GCGarbage Collection)所以JAVA程序员仅需要负责分配和使用内存即可而释放内存则由GC负责。这样程序员就从讨厌的内存管理的工作中脱身了。本文主要给大家介绍一下JVM如何查找需要被回收的对象实例与垃圾收集算法。查找可回收对象我们都知道垃圾回收机制是将内存中不可能在被使用的的对象实例(可回收的对象实例)回收释放其所占用的内存以供其他对象使用。JAVA的垃圾回收机制是对JAVA堆和方法区的内存回收。那么CG是怎么知道该对象是否还会使用呢一、引用计数算法(Reference Counting)引用计数算法简单的讲就是给每个对象中添加一个引用计数器 每当有一个地方引用它时计数器值就加1:当引用失效时计数器值就减1当对象的计数器为0就表示该对象已“死”可以被回收了。虽然这种算法实现简单判定效率也高。但是大部分JAVA虚拟机却没有使用此算法因为这个算法很难解决对象之间互相循环引用的问题。二、可达性分析算法(Reachability Analysis)可达性分析算法是通过被称为 “GC Roots 的对象作为起始点 从这些节点开始向下搜索搜索所走过的路径称为引用链(Reference Chain)当一个对象到GC Roots没有任何引用链相连就是从GC Roots到这个对象不可达时则证明此对象是不可用的。如图1.1。对象 2、对象 4、对象 6不可到达GC Roots所以会被回收。图1.1垃圾收集算法通过上文我们知道了JVM如何查询需要被回收的对象实例那么JVM是通过什么方法把对象收回的呢不同虚拟机回收内存的方法各不相同主流的方法有标记-清除算法、复制算法、标记-整理算法和分代收集算法。一、标记-清除算法(Mark-Sweep)标记-清除算法分为“标记”和“清除”两个阶段:首先标记出所有需要可收的对象在标记完成后统一回收所有被标记的对象。如上文所介绍标记过程其实就是找出不可能在被使用的对象实例。如图1.2首先标记出需要被回收的对象然后将这些对象回收回收后的状态如图1.3。回收前状态 图1.2回收后状态 图1.3标记-清除算法主要有两个不足:一个是效率问题 标记和清除两个过程的效率都不高;另一个是空间问题标记清除之后会产生大量不连续的内存碎片空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。二、复制算法(Copying)复制算法将可用内存容量划分为大小相等的两块每次只使用其中的一块。当这一块的内存用完了就将还存活着的对象复制到另外一块上面然后再把已使用过的这一块的内存空间全部清理掉。这样使得每次GC是对整半个内存区域进行回收内存分配时也就不用考虑内存碎片等问题只要移动堆指针按顺序分配内存即可。这种方式实现简单运行高效。但是这种算法的代价是将内存缩小为原来的一半未免太高了一点。复制算法的执行过程如图1.4与图1.5所示。回收前状态 图1.4回收后状态 图1.5三、标记-整理算法(Mark-Compact)标记-整理算法标记过程与标记-清除算法一样但后续步骤不是直接对可回收对象进行清理而是让所有存活的对象都向一端移动 然后直接清理掉端边界以外的内存“标记-整理”算法的过程如图1.6与图1.7所示。回收前状态 图1.6回收后状态 图1.7四、分代收集算法(Generational Colllection)当前主流虚机的垃圾收集都采用“分代收集”这种算法并没有什么新的思想只是根据对象存活周期的不同将内存划分为几块。一般是把JAVA堆分为新生代和老年代(新生代与老年代后续会有文章介绍)这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中每次垃圾收集时都发现有大批对象死去只有少量存活那就选用复制算法只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、所以使用“标记-清除”或者“标记-整理” 算法来进行回收。更多文章可关注微信公众号IT鸡窝