JVM 垃圾回收之复制算法

妖狐艹你老母 2022-08-31 11:01 237阅读 0赞

一 背景

为了解决标记-清除算法在垃圾收集效率方面的缺陷,M.L.Minsky 于1963 年发表了著名的论文,“使用双存储区的 Lisp 语言垃圾收集器 CA LISP Garbage Collector Algorithm Using Serial Secondary Storage)”。M.L.Minsky 在该论文中描述的算法被人们称为复制(Copying)算法,它也被 M.L.Minsky 本人成功地引入到了 Lisp 语言的一个实现版本中。

二 核心思想

将活着的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5ncWl1bWluZw_size_16_color_FFFFFF_t_70

把可达的对象,直接复制到另外一个区域中复制完成后,A区就没有用了,里面的对象可以直接清除掉,其实里面的新生代就用到了复制算法。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5ncWl1bWluZw_size_16_color_FFFFFF_t_70 1

三 优点

  • 没有标记和清除过程,实现简单,运行高效。
  • 复制过去以后保证空间的连续性,不会出现“碎片”问题。

四 缺点

  • 此算法的缺点也是很明显的,就是需要两倍的内存空间。
  • 对于 G1 这种分拆成为大量 region 的 GC,复制而不是移动,意味着 GC 需要维护 region 之间对象引用关系,不管是内存占用或者时间开销也不小。

五 注意

如果系统中的垃圾对象很多,复制算法需要复制的存活对象数量并不会太大,或者说非常低才行(老年代大量的对象存活,那么复制的对象将会有很多,效率会很低)。

在新生代,对常规应用的垃圾回收,一次通常可以回收 70% - 99% 的内存空间。回收性价比很高。所以现在的商业虚拟机都是用这种收集算法回收新生代。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5ncWl1bWluZw_size_16_color_FFFFFF_t_70 2

发表评论

表情:
评论列表 (有 0 条评论,237人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JVM垃圾回收算法

    前言 第二篇介绍了`Java`内存运行时区域,其中程序计数器、虚拟机栈、本地方法栈 三个区域随线程而生,随线程而灭;栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和

    相关 jvm垃圾回收算法

    垃圾回收算法 哪些内存需要回收 jvm的内存模型中将内存划分为程序计数器、虚拟机栈、本地方法栈、堆、方法区。 其中程序计数器、虚拟机栈、本地方法栈属于线程私有的内

    相关 jvm垃圾回收算法

    一:分代回收算法 1:为什么会有年轻代? 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能。你先想

    相关 JVM垃圾回收算法

    Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法。 在Java堆上分配一个内存给实例对象时,此时

    相关 JVM垃圾回收算法

    ![0][] JVM之垃圾回收算法 ![d3hfZm10PXBuZw][] 相比如C++,Java程序的一大优势是不需要程序员手动释放分配的内容,主要由Java虚拟机管理