上篇文章我们了解到哪些内存区域和哪些对象可以被回收,这篇文章我们就来了解一下具体的垃圾回收算法的思路,不讨论具体的实现。

  一 最基础算法 标记-清除(Mark-Swap)

  为什么说他是最基础的算法,因为这之后的算法思路都是基于此来进行。如同他的名字一样,回收分为两个步骤,标记和清除,但是这种方式有两个缺陷,一是效率问题,标记和清除两个过程的效率都不高;二是空间问题,回收后可能产生大量的内存碎片,当需要给大对象分配内存空间的时候,有可能会导致提前触发一次垃圾回收:

  

  二 复制算法(Copying)

  为了结解决效率问题,一种名为复制的回收算法出现了,它会将新生代的内存分为两块相等的区域,一块成为Eden,另一块称之为Survivor,新生对象在Eden区域分配内存,经历一次垃圾回收之后,将存活的对象复制到Survivor区域,同时清空Eden区域,但是这样做会导致新生代50%的内存浪费,根据IBM的研究,大多数情况下,新生代的对象有98%是无法存活到下一次垃圾回收的,HotSpot虚拟机会将新生代按照8:1:1的比例分为一个Eden和两个Survivor区域(s1和s2),道理一样,新生对象在Eden分配内存区域,但是,为什么要分配两个survivor区域呢?答案是为了保证内存的连续性,按照虚拟机的规定,新生的对象经历过16次垃圾回收后仍旧存活的话,才会将其分配到老年代,一个survivor区域只能满足一次回收后的内存连续性,survivor总有一个为空的准备接受存活对象,具体过程如下:当触发垃圾回收时,Eden和s1中的存活对象会被复制到s2中,同时清空Eden和s1,下次再触发垃圾回收时,将Eden和s2中存活的对象分配到s1中,清空Eden和s2,s1和s2轮流保存存活对象,才能保证存活对象的内存连续性。

  三 标记-整理算法(Mark-Compact)

  当对象的存活效率较高时,复制的效率会很低,所以又引出了这种算法,思路是:标记的过程都一样,但后续不是对可回收对象进行清理,而是让所有存活对象向同一端移动,然后直接清理掉端边界以外的内存:

  

  以上就是几种主流算法的实现思路,但是很明显,某一种算法都不能完全满足所有内存区间的高效回收,所以,现代的商用虚拟机都是根据不同区域对象的生存周期特征采用分代收集来实现。在Java中,会将堆内存分为新生代和老年代,在新生代中,每次垃圾收集会有大量的对象死去,只有少量存活,复制成本低,就适合采用复制算法;在老年代中,对象存活率高,就必须使用标记-整理算法来进行回收。

  至此,我们了解了Java虚拟机内存回收算法的几种实现思路以及分别适应什么场景,下一篇文章我们将会了解这其中的具体实现中遇到的问题以及应该如何解决。

深入理解JVM(五) -- 垃圾回收算法的更多相关文章

  1. 深入理解JVM一垃圾回收算法

    我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理. 一.stop the world 在介绍 ...

  2. JVM(九):垃圾回收算法

    JVM(九):垃圾回收算法 在本文中,我们将从概念模型的角度探讨 JVM 是如何回收对象,包括 JVM 是如何判断一个对象已经死亡,什么时候在哪里进行了垃圾回收,垃圾回收有几种核心算法,每个算法优劣是 ...

  3. jvm详情——3、JVM基本垃圾回收算法回收策略

    JVM基本垃圾回收算法回收策略 引用计数(Reference Counting):比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的 ...

  4. JVM G1垃圾回收算法简要介绍

    JVM G1垃圾回收算法简要介绍 G1的特点 能够像CMS垃圾回收算法一样并发操作应用线程(潜台词:多核) 无需太长时间即可压缩空闲内存空间(潜台词:不会引起太多的GC停顿时间) 尽可能地让GC时长可 ...

  5. jvm的垃圾回收算法

    一.对象存活判断判断对象是否存活一般有两种方式:1.引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收.此方法简单,无法解决对象相互循环引用的问题.2 ...

  6. 深入探究JVM之垃圾回收算法实现细节

    @ 目录 前言 垃圾回收算法实现细节 根节点枚举 安全点 安全区域 记忆集和卡表 写屏障 并发的可达性分析 低延迟GC Shenandoah ZGC 总结 前言 本篇紧接上文,主要讲解垃圾回收算法的实 ...

  7. JVM常见垃圾回收算法

    jdk1.7.0_79 众所周知,Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法.本文将介绍几种常见的垃圾回收(下文简称 ...

  8. jvm学习-垃圾回收算法(三)

     垃圾回收算法  引用计数法 比较古老的一种垃圾回收算法.在java的GC并没有采用 增加一个引用 引用+1 减少一个引用引用减一 每次清除引用为0的的对象 缺点:不能回收循环引用的垃圾对象 标记清除 ...

  9. 深入理解JVM——关于垃圾回收

    关于垃圾回收 仿佛来自上海居委会大妈的灵魂拷问:“你是什么垃圾?” 不 今天我们要说的是JVM的垃圾回收 假如我是一个“人”类的“对象”,也和人的生命一样必有一死,可是“我真的还想再活500年~~”, ...

随机推荐

  1. 菜鸟学IT之分布式文件系统

    作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3310 1.目录操作 在HDFS中为hadoop用户创建一个用户目录(had ...

  2. Ubuntu 16.04与Win10双系统双硬盘安装图解

    一.先做准备工作.建议:在当前系统所在的硬盘上,留一片空的主分区安装Ubuntu系统. 2.划分多大的空间够?安装的过程中需要涉及到分区,为了以免日后重装,我的建议是如下分区:1).5G,主分区,空间 ...

  3. windows服务器卸载补丁命令【转】

    一.可以试用cmd命令 wusa.exe /uninstall /kb: wusa.exe /uninstall /kb: wusa.exe /uninstall /kb:   二.使用DISM卸载补 ...

  4. 微信小程序实例:分享给一个人还是分享到群的判断代码

    微信小程序的分享功能,在最新版库的ide上已经不能拿到分享回调了,官方api也删除了对应的回调函数,看样子是砍掉了,不过真机测试还是可以的,话不多说,上代码: /* // 分享功能回调 onLoad: ...

  5. git切换分支冲突解决-删除分支

    在项目开发中,有多个版本分支需要不时的来回切换,在切换的过程中,产生了很多冲突,提交的时候 也提交不了.总结下在解决这个过程中使用的两种方法: 1.删除项目在磁盘的目录,包括 git 文件,重新 cl ...

  6. apt与apt-get命令的区别

    apt 和 apt-get的区别 Debian 作为 Ubuntu.Linux Mint 和 elementary OS 等 Linux 操作系统的母板,其具有强健的「包管理」系统,它的每个组件和应用 ...

  7. docker安装并运行redis

    拉取镜像: [mall@VM_0_7_centos ~]$ sudo docker pull redis:3.2 [sudo] password for mall: 3.2: Pulling from ...

  8. Spring cloud微服务安全实战-7-11PinPoint+SpringBoot环境搭建

    微服务的最后一个组件, 调用链监控,一个请求进来以后,经过N多个微服务,例如a调用了b.b又调用了c,那么在这个过程中看到,整个的调用的链路,然后每一段调用所耗费的时间,帮你去分析你的系统如果出现瓶颈 ...

  9. js 模糊搜索

    function fuzzysearch (needle, haystack) { var hlen = haystack.length; var nlen = needle.length; if ( ...

  10. 容器版jenkins使用宿主机的docker命令

    参照里面的第一步里面的dockerfile: https://www.cnblogs.com/effortsing/p/10486960.html