第三章 垃圾收集器与内存分配策略

Java虚拟机共有五个区域,其中三个线程私有:程序计数器虚拟机栈本地方法栈,两个是线程共享:方法区。线程私有区域等到线程结束时会自动释放,而线程共享的java堆和方法区中的空间较大而且没有线程的回收容易产生很多垃圾信息,GC垃圾回收真正关心的就是这部分。
那么我们在使用GC对其进行回收的时候首先要考虑的就是如何判断一个对象是否应该被回收。也就是要判断一个对象是否还有其他的引用或关联使得这个对象处于存活的状态。我们需要将不在存活状态的所有对象标记出,以便于GC进行回收。

判断对象是否存活有两种比较常见的方法:引用计数法可达性分析算法


引用计数算法

这里写图片描述

给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就+1,;当引用失效时,计数器值就-1;任何时刻计数器为0的对象就是不可能在被使用。

缺点:
不会完全准确,因为如果出现两个对象相互引用的问题就不行了。
这里写图片描述

这里写图片描述

很明显,两个实例到最后都不用了,都为null,但是GC却不能回收,因为引用数不是0,而是1,这就造成了内存泄漏。也很明显,现在虚拟机都不采用此方式。

可达性分析算法:

从一个被称为GC Roots的对象开始向下搜索,如果一个对象到GC Roots没有任何引用链相连时,则说明此对象不可用。

这种算法目前定义了几个root,也就是这几个对象是jvm虚拟机不会被回收的对象,所以这些对象引用的对象都是在使用中的对象,这些对象未使用的对象就是即将要被回收的对象。简单就是说:如果对象能够达到root,就不会被回收,如果对象不能够达到root,就会被回收。

由于这种算法即使存在互相引用的对象,但如果这两个对象无法访问到根对象,还是会被回收。如下图:对象C和对象D互相引用,但是由于无法访问根,所以会被回收。
这里写图片描述

在root搜索算法的里面,我们说的引用这里指的是强引用关系。所谓强引用关系,就是通过new方式创建的对象,并且显示关联的对象。
Object obj = new Object();
以上代表的就是强硬引用关系,变量obj 强引用了 Object的一个对象。

四种引用:

  • 强引用:
    通常,我们通过new来创建一个新对象时,返回的引用就是一个强引用。
  • 软引用:
    软引用和弱引用的区别在于,若一个对象是弱引用可达,无论当前内存是否充足它都会被回收,而软引用可达的对象在内存不充足时才会被回收,因此软引用要比弱引用“强”一些
  • 弱引用:
  • 虚引用:

什么是Java的弱引用?

弱引用就是不保证不被垃圾回收器回收的对象,它拥有比较短暂的生命周期,在垃圾回收器扫描它所管辖的内存区域过程中,一旦发现了只具有弱引用的对象,就会回收它的内存,不过一般情况下,垃圾回收器的线程优先级很低,也就不会很快发现那些只有弱引用的对象。

在Java中,可以作为GC Roots的的对象有一下几种:
虚拟机栈中引用的对象、方法区类静态属性引用的对象、方法区常量池引用的对象和本地方法栈JNI引用的对象。

引用计数法与可达性分析算法

垃圾收集算法

标记-清除算法

算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
主要有两个不足之处:一个是效率问题,标记和清除两个的效率都不高;另一个是空间问题,标记和清除后回产生大量的不连续的内存碎片。

复制算法

他将可用内存按容量大小划分为大小相同的两块,每次只使用其中的一块。当一块内存用完了,就将还存活着的对象复制到另外一块上,然后把已使用过的内存空间一次清理掉。这样就使得每次都是对整半个内存区域进行回收,内存分配时也就不用考虑内存碎片等复杂情况。

标记-整理算法

标记:它的第一个阶段与标记/清除算法是一模一样的,均是遍历GC Roots,然后将存活的对象标记。
整理:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。因此,第二阶段才称为整理阶段。
不难看出,标记/整理算法不仅可以弥补标记/清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内存减半的高额代价,可谓是一举两得,一箭双雕,一石两鸟啊!
  不过任何算法都会有其缺点,标记/整理算法唯一的缺点就是效率也不高,不仅要标记所有存活对象,还要整理所有存活对象的引用地址。从效率上来说,标记/整理算法要低于复制算法。

复制算法&标记整理算法

分带收集算法

根据对象存活周期的不同将内存划分为几块。一般把Java堆分为新生带和老年代,这样就可以根据各个年代的特点采用最适合的收集算法。在新生带中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法。在老年带中,由于对象存活率高,所以采用“标记-清理”或“标记-整理”算法来进行回收。

猜你喜欢

转载自blog.csdn.net/qq_32682177/article/details/82430839