JVM 垃圾回收GC

一、如何判断对象是垃圾对象

     1.引用计数法

            在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值+1,失效则-1。但是两个相互引用的对象有可能无法回收。

private Object instance;
Demo demo1 = new Demo();
Demo demo2 = new Demo();
demo1.instance = demo2;
demo2.instance = demo1;
demo2 = null;
demo1 = null;
System.gc();

     2.可达性分析

    根据GCRoots节点来搜索,遍历过得路径,当对象不再引用链上,则对象可以被回收(没有被引用)。

    GCRoots对象:

        虚拟机栈、方法去中类属性引用的对象、方法区中常量引用的对象、本地方法栈中引用的对象。

二、如何回收

     1.回收策略

         (1)标记-清除

               1.标记:标记出需要回收的对象

               2.清除:清除无效的对象       

           缺点:清除对象过程中,将对象内存占用的内存清空,但不会整理内存空间,这导致内存的地址是不连续的。当需要分配新对象的内存时,需要在内存的一张维护表里面寻找可用的连续的内存,如果没有找到则会触发GC。 这样会造成效率的浪费和空间内存的浪费。  

         (2)复制

            堆内存分为 一个eden和两个survivor区域,内存比例是8:1:1。在未发生GC前,内存中产生的对象存储在eden区域和一个Survivor区域。当着两个区域都存满时,会触发GC,将存活下来的对象实例存储到第二个survivor区域。这个区域和eden区域将会作为新的内存区域来存放新产生的对象。

       (3)标记-整理 (针对老年代回收的算法)

             标记需要清除的对象,将需要清除的对象和保留的对象移动至两个区域,进而清除对象。这样的算法可以使得清楚后的内存区域是完整连续的区域。

         (4)分代收集算法

             分代收集算法是根据不用的区域采用不用的算法来进行GC,新生代区域采用复制算法,老年代采用标记-整理算法。这样的分配规则使得不同区域的GC性能更加高效。

猜你喜欢

转载自blog.csdn.net/qq_28126793/article/details/83513897