基本概念

  • GC复制算法将堆分成From和To两个内存块,当From被占满时GC将From中的存活对象复制到To中,同时将From和To交换。
  • 通过递归遍历GC root(即采用深度优先)复制存活对象,对于已经复制过的标记其COPIED字段。
  • 复制过的对象将在From的对象的forwarding记录To中该对象地址,以便于其余引用了该对象的引用进行修改。
  • 分配对象时将先判断From中连续可用空间是否够用(复制算法不存在碎片),如果不够则进行一次GC,还不够则分配失败。

优缺点

优点

  1. 吞吐量大,只需要遍历一次From空间Sweep需要遍历两次,而且只复制存活的对象。
  2. 高速分配,不需要通过空闲链表直接在连续的内存上进行分配。
  3. 没有碎片。
  4. 与缓存兼容,复制存活对象时采用深度优先算法使相关联的对象都在附近。

缺点

  1. 堆的使用效率低,必须分配一个To,其不能分配对象。
  2. 不兼容保守式GC算法,需要移动对象。
  3. 递归调用,复制对象的深度优先算法是通过递归调用实现的,递归将消耗栈等资源。

改进

Cheney的GC复制算法

针对递归

  • 复制算法的To中增加scan指针,其指向To中已经复制过所有子对象位置。
  • 首先将GC root直接引用的对象复制到To中,而后通过scan指针的移动对后续存活对象进行复制。实现了广度优先搜索算法
  • 通过scan在To中的移动实现了一个隐式的FIFO队列。
  • 取消COPIED字段,通过forwarding字段是否指向To区间来判断该对象是否已被复制。
  • 优点在于取消了递归,缺点则是采用了广度优先算法使其与缓存不兼容。

近深度优先搜索方法

针对Cheney的复制算法中与缓存不兼容问题

  • page:堆分隔成一个个页面的数组;local_scanf:每个页中搜索用的指针作为元素的数组;major_scan:指向未搜索完的页面开头;free:分块开头;
  • 第一阶段从GC root中将其直接引用复制到第一个页中。
  • 而后对每个对象按照类似深度优先算法,区别在于其原始深度优先算法每层一次只搜索一个对象而该算法则将同一层一次搜索完 此处没懂,还有页占满的问题

多空间复制算法

针对堆利用率低

  • 将堆分成多份,每次取其中的两个分别作为From和To,其余则采用Mark-Sweep算法。
  • From总在To的右边的块中,每执行一次GC,From和To均向右移动一个块。
  • 在GC时先进行标记阶段,当存活对象处于From时执行copy,当处于其余块时执行mark。
  • 优点在于提高了堆的利用率,缺点则是引入了Mark-Sweep算法导致STW时间变长,分块得采用空闲链表

《垃圾回收的算法与实现》——GC复制算法的更多相关文章

  1. JVM内存管理------GC算法精解(复制算法与标记/整理算法)

    本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...

  2. JVM内存管理之GC算法精解(复制算法与标记/整理算法)

    本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...

  3. JVM-GC算法(二)-复制算法&&标记整理算法

    这次我和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一篇在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算法 ...

  4. JVM_垃圾回收串行、并行、并发算法(总结)

    一.串行 JDK1.5前的默认算法 缺点是只有一个线程,执行垃圾回收时程序停止的时间比较长 语法 -XX:+UseSerialGC 新生代.老年代使用串行回收 新生代复制算法 老年代标记-压缩 示例图 ...

  5. JVM垃圾回收(二)- Minor GC vs Major GC vs Full GC

    Minor GC vs Major GC vs Full GC 垃圾回收的活动会清理对内存中的不同区域,这些事件一般被称为Minor,Major以及Full GC events.本章我们会讨论这些清理 ...

  6. Java 垃圾回收机制方法,判断对象存活算法

    垃圾回收机制: 不定时去堆内存中清理不可达对象.不可达的对象并不会马上就会直接回收, 垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回 ...

  7. 【JVM第八篇--垃圾回收】GC和GC算法

    写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 1.垃圾 1.1.什么是垃圾 垃圾(Garbage)在Java语言中是指在运行程序中 ...

  8. Java JVM运行时数据区,内存管理和GC垃圾回收

    一 . 运行时数据区 程序计数器是线程私有的,是一块很小的内存空间,是当前线程执行到字节码行号的计数指示器.每个CPU处理器核心 在任何一个时刻,都只可能运行着唯一的一个线程,执行着一条指令.所以在多 ...

  9. Java的垃圾回收和内存分配策略

    本文是<深入理解Java虚拟机 JVM高级特性与最佳实践>的读书笔记 在介绍Java的垃圾回收方法之前,我们先来了解一下Java虚拟机在执行Java程序的过程中把它管理的内存划分为若干个不 ...

随机推荐

  1. 让tableView的某行移动到tableView的某位置

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lineNumber inSection:0]; [lrcTableView selectR ...

  2. css布局:定宽,自适应

    css三栏布局:1.中自:float,absolute,margin三种方法.2.中固:margin,table两种方法. 两边定宽,中间自适应: float: #left{ float:left; ...

  3. java socket编程(也是学习多线程的例子)详细版----转

    7.2 面向套接字编程    我们已经通过了解Socket的接口,知其所以然,下面我们就将通过具体的案例,来熟悉Socket的具体工作方式 7.2.1使用套接字实现基于TCP协议的服务器和客户机程序  ...

  4. 面向对象编程思想(前传)--你必须知道的javascript(转载)

    原文地址:http://www.cnblogs.com/zhaopei/p/6623460.html阅读目录   什么是鸭子类型 javascript的面向对象 封装 继承 多态 原型 this指向 ...

  5. CSharp程序员学Android开发---3.Android内部元素不填充BUG

    最近公司组织项目组成员开发一个Android项目的Demo,之前没有人有Andoid方面的开发经验,都是开发C#的. 虽说项目要求并不是很高,但是对于没有这方面经验的人来说,第一步是最困难的. 项目历 ...

  6. Replication--查看未分发命令和预估所需时间

    当复制有延迟时,我们可以使用复制监视器来查看各订阅的未分发命令书和预估所需时间,如下图: 但是当分发和订阅数比较多的时候,依次查看比较费时,我们可以使用sys.sp_replmonitorsubscr ...

  7. asp.net—单例模式

    一.单例模式是什么? 定义:确保一个类仅仅能产生一个实例,并且提供一个全局访问点来获取该实例. 二.单例模式怎么用? class SingleCase { public string Name{get ...

  8. C#检测并安装https站点的数字证书,CefSharp和HttpWebRequest通过会话Cookie实现自动登录访问https站点

    HttpUtil工具类: using System; using System.Collections.Generic; using System.IO; using System.Linq; usi ...

  9. DI spring.net简单使用

    IOC或DI  spring.net简单使用 一.spring.net是什么? Spring 框架本是 Java 平台上一个应用非常多的.开源的框架.虽然语言是固定的,但是好的方法应该是通用的,于是 ...

  10. Docker之存储管理

    本文由作者邹珍珍授权网易云社区发布. 本文主要介绍Docker的存储管理.Docker拥有镜像分层,写时复制机制以及内容寻址存储等特征,为了支持这些特征,Docker设计了一套镜像元数据管理机制来管理 ...