首页 > 代码库 > 对象是否有被引用判断及垃圾收集算法
对象是否有被引用判断及垃圾收集算法
1、引用计数算法
给对象中添加一个计数器,每当一个地方引用它时,计数器值就加1;当引用失效时就减1。如果两个对象存在相互的引用,尽管这两个引用已经不再被使用,但还是不能被清除。通过一些实验可得SUN公司的JVM没有采用这种算法。
2、根搜索算法
该算法的基本思路是通过一系列的名为“GCRoots” 的对象作为起点,从这些起点开始向下搜索。搜索所通过的路径(引用链:Reference chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。在JAVA里可用做GC Roots的对象有:虚拟机栈中的引用对象、方法区中的类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI(一般说的Native method)引用的对象
垃圾收集算法:
1、标记-清除算法(mark-sweep)
这是最基础的算法,在内存中判断对象还有没有被引用,如果没有则被标记,最后被清除,该算法会在后面的算法中使用。
缺点:a 标记、清除效率不高。
b 清除后会产生大量不连续的碎片,在分配较大的对象时可能因为找不到合适的完整的内存区域,而进行第二次垃圾收集。
2、复制算法(copying)
是指把内存区域一分为二,在第一块区域中的存活对象搬迁到第二块区域中,然后前一块一次清理掉,迁移只需要移动堆指针。简单高效。
缺点:把内存降为原来的一半。
实际的商业运用中,比例不一定是1:1,他会根据内存中的特征来设计合适的比例。 比如:HotSpot虚拟机默认的Eden与Survivor的空间为8:1(内存会被分为一个Eden和两个Survivor,只使用Eden和其中一个Survivor),所以使用了90%的空间。如果其他场景内存不够够则会需要使用其他内存来进行担保。
3、标记-整理算法
是指把所有存活的对象向一端移动,然后直接清楚掉端边界面以外的内存。
4、分代收集算法
是指跟据不同的特点,把它们分到不同的区域。一般是把Java堆分为新生代和老年代,这样就可以根据期特点,使用不同的算法收集。新生代在收集时会有大批对象死亡从而可以采用复制算法,老年代的对象存活率比较高,则可以使用标记-清理算法或标记-整理算法。
对象是否有被引用判断及垃圾收集算法