JVM中释放内存的三种方法

判断是否需要垃圾回收可以采用分析。

1标记--清除算法

分为两个阶段,标记和清除,先利用可达性分型标记还存活的对象,之后将没有被标记的对象删除,这样容易生成空间碎片,而且效率不稳定

  1. 标记阶段:
    标记阶段与可达性分析算法类似,通过从根对象开始遍历对象引用链,标记所有被访问到的对象为存活对象。标记完成后,所有存活对象被标记为"已存活"。

  2. 清除阶段:
    清除阶段是标记-清除算法的特有步骤。在该阶段,算法扫描整个堆内存,找到未被标记的对象,并进行清除操作。清除的对象被认定为垃圾对象,即可以被垃圾回收器回收内存。

清除操作有两种常见的方式:

  • 逐个清除:对于每个未被标记的对象,将其从内存中移除,并释放其占用的内存空间。
  • 延迟清除:将所有未被标记的对象的内存空间标记为可用,而不立即释放。可以在需要申请新内存时,直接将可用空间分配给新对象,避免频繁的内存分配和释放操作。

速 度 较 快

会 造 成 内 存 碎 片

 2.标记整理算法

  1. 标记阶段:
    标记阶段与可达性分析算法类似,通过从根对象开始遍历对象引用链,标记所有被访问到的对象为存活对象。标记完成后,所有存活对象被标记为"已存活"。

  2. 整理阶段:
    整理阶段是标记-整理算法的特有步骤。在该阶段,算法将所有存活对象移到内存的一端,然后对非存活对象所占用的空间进行回收,使之成为可用的内存空间。

整理阶段分为两个步骤:

  • 从内存的起始位置开始,依次遍历所有存活对象,并将其按顺序移动到内存的另一端。移动过程中,保持对象之间的引用关系不变,即更新引用指向新的位置。
  • 在移动完所有存活对象后,释放剩余的内存空间,使之变为可用的内存。

通过标记-整理算法,内存中只保留了存活对象,并且实现了内存的紧凑布局,使得存活对象在内存中连续存放。相比于标记-复制算法,标记-整理算法没有额外的空间浪费,适用于老年代等内存较大的场景。

避免内存碎片的产生,第一阶段也是标记对象,和标记清除的区别在于第二阶段的整理,它是将存活的对象移动到头部

速 度 慢

没 有 内 存 碎 片

3.标记复制法

  1. 标记阶段:
    标记阶段与可达性分析算法类似,通过从根对象开始遍历对象引用链,标记所有被访问到的对象为存活对象。标记完成后,所有存活对象被标记为"已存活"。

  2. 复制阶段:
    复制阶段是标记-复制算法的特有步骤。在该阶段,算法将内存空间划分为两个相等大小的区域,通常称为"From空间"和"To空间"。初始时,所有存活对象位于From空间。

复制阶段分为两个步骤:

  • 从From空间开始,对已标记的存活对象进行复制到To空间。复制过程中,保持对象之间的引用关系不变,即更新引用指向新的位置。复制完成后,From空间中的所有对象都是垃圾。
  • 将From空间与To空间进行交换,使To空间成为新的From空间,原From空间成为新的To空间,此时完成了垃圾回收。

通过标记-复制算法,内存中只保留了存活对象,将垃圾对象全部清理,并且实现了内存的紧凑布局,使得存活对象在内存中连续存放,提高了内存访问的性能。

不 会 有 内 存 碎 片

需 要 占 用 双 倍 内 存 空 间