java垃圾回收机制简单介绍

JAVA垃圾回收机制(GC)简单介绍

  • java中的垃圾回收机制(Garbage Collection, GC)使得我们程序员写程序时不用去关心内存动态分配和垃圾回收的问题,这一切工作都由JVM来处理。虽然我们不需要去处理这些工作,但我们还是有必要了解下java垃圾回收机制的基本原理,毕竟在某些情况是需要我们根据垃圾回收的机制来保证程序的健壮性的(防止内存泄漏).

首先我们要明白两个问题:

  1. 在Java中,什么对象会被定义为”垃圾”?
  2. 在执行垃圾回收过程中,虚拟机采用了什么回收算法来执行垃圾回收的?

1.什么对象会被定义为”垃圾”?

在java中是通过引用来和对象进行关联的,也就是说如果要操作对象,必须通过引用来进行。那么就可以通过一个简单的方法引用计数来判断一个对象是否被回收,假如一个对象没有任何的一个引用与之关联,则该对象基本不大可能在其他地方被引用到,那个这个对象就可能成为被回收的对象。
该方法实现简单,且效率高。但是,该方法也存在一定的缺点,无法解决循环引用的方法。什么是循环引用?给一段代码展示

public class App{
    public static void main(String[] args) {
        Test object1 = new Test();
        Test object2 = new Test();

        object1.object = object2;
        object2.object = object1;

        object1 = null;
        object2 = null;
    }
}

class Test{
    public Test object = null;
}

虽然最后两句将object1和object2置为null,但是他们由于互相引用,结果导致它们的计数都不为0,那些垃圾收集器就无法回收它们.

所以为了解决这个问题,java中采取了可达性分析法。该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。

这种方法相比引用计数方就更加严谨了,并且可能解决循环引用的问题。

2.java虚拟机采取了什么算法来执行垃圾回收?

在回答这个问题之前,我们先了解下目前垃圾回收有哪几种主流的回收算法.
1).Mark-Sweep(标记-清除)算法
这是最基础的算法,该算法就是标记出需要被回收的对象,等到需要执行GC操作时将标记的对象一并清除,实现垃圾回收。改方法简单,效率高,但是有个缺点就是会导致内存碎片。

2).Copying(复制)算法
Copying算法是将内存区域划分为两块相同大小的子区域,并且在其中的一块中执行对象分配,等到这一块的内存用完了,就将该区域还存活着的对象复制到另外一块内存区域上面,然后再把已使用的内存空间一次清理掉,这样就不会导致内存碎片的问题,但是有个明显的缺点,每次只能使用到一半的内存,对内存压力大。

3).Mark-Compact(标记-整理)算法
Mark-Compact算法是在Mark-Sweep算法的基础上进行了改进,算法标记跟Mark-Sweep一样,只是在标记完之后,将标记的对象向一端移动,然后清理掉边界以外的内存区域,这样就解决了内存碎片化的问题

3).Generational Collection(分代收集)算法
这是目前Jvm使用的垃圾回收算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。分为老年代(Tenured Generation)和新生代(Young Generation)。老年代的内存区域的对象一般回收频率比较低,采用了Mark-Compact算法,而新生代的内存区域由于每次需要回收大量对象,回收频率较高,所以将该区域又划分成了一个较大的Eden空间和两个较小的Suivivor空间,每次使用Eden空间和一个Survivor空间的,当需要回收垃圾时,将Eden空间和该Survivor空间的存活对象复制到另外一块Survivor空间上,然后清理到Eden和刚才使用的Survivor空间,实现垃圾回收机制.

所以java垃圾回收机制主要关注的重点是可达性分析法还有分代收集算法,并且了解它们的优点。

你可能感兴趣的:(java)