关键词

Java GC垃圾回收算法分析

Java GC垃圾回收算法分析

什么是Java垃圾回收

Java垃圾回收是指在Java虚拟机运行时,对无用对象所占用的内存进行回收,以便为新的对象腾出空间。Java虚拟机中垃圾回收是一种自动化的过程,它不需要程序员手动干预,但是程序员可以通过代码的方式对垃圾回收过程进行影响。

Java垃圾回收算法

在Java虚拟机对内存进行垃圾回收时,需要选择一个合适的垃圾回收算法。目前Java垃圾回收算法主要有以下几种:标记-清除算法、复制算法、标记-整理算法和分代算法。

标记-清除算法

标记-清除算法是最基本的垃圾回收算法,其核心思想是将所有的内存块分为标记区和未标记区,回收时,先对所有的内存块进行标记,然后对所有未标记的内存块进行回收,达到释放内存的目的。该算法的优点是实现简单,缺点是容易产生内存碎片,影响内存的连续性。

复制算法

复制算法主要是应用于年轻代中,其核心思想是将原始内存分为两块,每次只使用其中的一块,当一部分内存使用完毕后,将其里面的存活对象复制到另一块内存中,然后将原来那部分内存全部清空,达到了释放内存的目的。该算法的优点是实现简单,回收高效,缺点是需要开辟两倍的空间,适用于内存较小的情况。

标记-整理算法

标记-整理算法是标记-清除算法的改进版本。该算法在移动标记区域的同时,整理出一个连续的空闲内存块,所有的对象都向这个方向移动。该算法的优点是解决了产生内存碎片的问题,缺点是实现比较麻烦。

分代算法

分代算法主要是应用于年轻代和老年代的垃圾回收。该算法基于一个事实,即大部分对象的生命周期都比较短暂,在年轻代中进行频繁的内存回收,而老年代中存储的对象生命周期长,较少进行回收。因此,基于这个事实,该算法分别针对年轻代和老年代采用不同的垃圾回收策略。其中,年轻代采用复制算法,老年代采用标记-整理算法或标记-清除算法。

示例说明

示例一:年轻代垃圾回收

当在Java虚拟机中执行一个程序时,JVM会为程序运行分配一块内存。假设在程序运行过程中,年轻代中的某一块内存已使用完毕,此时年轻代需要进行一次垃圾回收,此时JVM会使用复制算法进行内存回收。其回收过程如下:

  1. 将原始内存分为两部分,每次只使用一部分内存;
  2. 将使用完毕的一部分内存中所有存活的对象复制到另一部分内存中;
  3. 清空已经使用完毕的一部分内存中的所有内存块;
  4. 将原来使用的内存和新置换的内存进行互换。

复制算法的优点是垃圾回收高效,回收速度较快,但其缺点是需要开辟两倍的空间,适用于内存较小的情况。内存变化如下图所示:

+-----------------------+
|        old-gen        |
+-----------------------+
|   survivor-to-space   |
+-----------------------+
|   survivor-from-space |
+-----------------------+
|       eden-space      |
+-----------------------+

示例二:老年代垃圾回收

JVM中,老年代中的垃圾回收一般使用标记-清除算法或标记-整理算法,算法的选择取决于具体的对象分配情况。同时,标记-整理算法是标记-清除算法的改进版本,在执行过程中不会产生内存碎片。

在老年代中,一般采用分代算法,即将年轻代和老年代分别进行垃圾回收,因为大多数对象在分配后,会经历短时期的使用,并且在这个时间段内,生命周期相对比较短暂。

标记-整理算法中的垃圾回收过程如下:

  1. 将所有存活的对象进行标记;
  2. 整理出一个连续的空闲内存块,将所有对象向这个方向移动;
  3. 将没有存活对象所占用的内存回收,对于没有被移动的对象进行去标记。

标记-整理算法的优点是没有内存碎片的问题,缺点是实现比较麻烦。内存变化如下图所示:

+-----------------------+
|      non-continuous   |
|   memory blocks       |
+-----------------------+
| continuous memory     |
| blocks after          |
| defragmentation       |
+-----------------------+

本文链接:http://task.lmcjl.com/news/7960.html

展开阅读全文