JVM之GC算法

1. 前言

  1.1 概念:清理内存中不会再被使用的对象

  1.2 背景:如果内存中的垃圾不被清理,会导致内存溢出

  1.3 常用的垃圾回收算法:引用计数法(Reference Counting)、标记清除法(Mark-Sweep)、复制算法(Copying)、标记压缩法(Mark-Compact)、分代算法(Generational Collecting)及分区算法(Region)

2. 算法演进

  2.1 引用计数法【Java垃圾回收未采用】

    2.1.1 思想:对于对象A,如果被引用,A的引用计数器就+1;当引用失效时,A的引用计数器-1.当对象A的引用计数器的值为0,则对象A被回收。

    2.1.2 缺陷:

      2.1.2.1  无法处理循环引用的情况。【例如:对象A和对象B相互引用,却没有被其他对象引用。此时,A和B应该被回收。然而,对象A和B的引用计数器却不为0,无法被回收。】

      2.1.2.2 每次对象被引用/释放引用的时候,都会伴随着运算操作,对系统性能会有一定的影响。

因为循环引用的对象无法被回收,为了解决该缺陷,于是产生了可达对象的概念。根据可达对象的概念,产生了标记清除法。

  2.2 标记清除法【现代垃圾回收算法的基础】

    2.2.1 基础:

      2.2.1.1 可达对象:通过根对象进行引用搜索,最终可以达到的对象。

      2.2.1.2 不可达对象:通过根对象进行引用搜索,最终没有被引用到的对象。

    2.2.2 思想:通过标记、清除两个阶段实现垃圾回收

      2.2.2.1 标记阶段:根据根节点,标记所有的可达对象

      2.2.2.2 清除阶段:清除所有的不可达对象

    2.2.3 缺陷:

      2.2.3.1 产生大量的空间碎片,工作效率低

      标记清除法是对一块连续的空间进行回收,回收后的空间是不连续的【如图】。在对象的堆空间分配过程中,尤其是大对象的内存分配,不连续内存空间的工作做效率要低于连续空间。

因为不连续内存空间的工作效率低,为了解决这个问题,于是想到:新开辟一个工作空间,将可达对象复制到新的内存空间,保证空间使用的连续性。

  

  2.3 复制算法【新生代算法】

    2.3.1 思想:将原有的内存空间分为两块,每次使用其中一块。垃圾回收时,将正在使用的内存中的可达对象复制到未使用的内存块中,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成回收。

  2.3.2 缺陷:

    2.3.2.1 将系统内存折半,占用的系统内存太大。

复制算法的高效性是建立在存活对象少,垃圾对象对象多的前提下。对于存活对象多的情况,复制成本高,需要其它算法来替代。

  2.4 标记压缩法【老年代算法】

    2.4.1 原理:标记清除算法执行完成后,再进行一次内存碎片整理。

    2.4.2 思想:从根节点出发,将所有的可达对象进行标记,然后将标记对象压缩到内存的一端。最后,清除边界之外的所有空间。

在上述算法中,它们都有各自独特的优势,并没有一种算法可以完全替代其它算法。因此,正确的方式是:根据垃圾回收对象的特性,使用合适的算法回收。基于这种情况,产生了分代的思想。

  2.5 分代算法

    2.5.1 思想:根据对象的特点,将内存区域分成几块;根据每块内存区域的特点,使用不同的回收算法。

    2.5.2 应用:新生代使用复制算法,老年代使用标记压缩法。

既然可以根据对象的生命周期(时间角度)进行回收,那么根据对象的空间分布(空间角度)也可以进行回收。

  

  2.6 分区算法

    2.6.1 背景:在相同条件下,堆空间越大,一次GC所用的时间越长,从而产生的停顿也越长。

    2.6.2 思想:将堆空间划分成连续的小区域,每个小区域独立使用、独立回收。

3. 补充

  3.1 新生代串行垃圾回收器中,使用复制算法的思想。

    3.1.1 基础:新生代分为eden区、from区、to区。其中,from区和to区也被称为survivor区,可以视为用于复制的大小相等、地位相等、且可以角色互换的两个空间块。

    3.1.2 思路:垃圾回收时,Eden区和正在使用的survivor区(假设是from区)中的可达对象会被复制到未被使用的survivor区(to区),然后清空Eden区和from区。

    3.1.3 备注:from区中的大对象或者老年对象会直接进入老年区;如果to区空间不足,对象也会进入老年区

  3.2 复制算法的高效性是建立在可达对象少,不可达对象多的前提下,因此复制算法只用于新生代【新生代,垃圾对象通常会多于存活对象;老年代大部分对象都是存活对象】。老年代采用标记压缩法

  3.3 新生代GC与老年代GC对比:

4. 附录

  4.1 参考文献:《实战Java虚拟机 – JVM故障诊断与性能优化》 葛一鸣著

原文地址:https://www.cnblogs.com/BlueStarWei/p/9577388.html

时间: 2024-08-29 19:58:20

JVM之GC算法的相关文章

JVM的四种GC算法

程序在运行过程中,会产生大量的内存垃圾(一些没有引用指向的内存对象都属于内存垃圾,因为这些对象已经无法访问,程序用不了它们了,对程序而言它们已经死亡),为了确保程序运行时的性能,java虚拟机在程序运行的过程中不断地进行自动的垃圾回收(GC).关于 JVM 的 GC 算法主要有下面四种: 1.引用计数算法(Reference counting) 每个对象在创建的时候,就给这个对象绑定一个计数器.每当有一个引用指向该对象时,计数器加一:每当有一个指向它的引用被删除时,计数器减一.这样,当没有引用指

JVM之GC算法的实现(垃圾回收器)

上一节:<JVM之GC算法> 知道GC算法的理论基础,我们来看看具体的实现.只有落地的理论,才是真理. 一.JVM垃圾回收器的结构 JVM虚拟机规范对垃圾收集器应该如何实现没有规定,因为没有最好的垃圾收集器,只有最适合的场景. 图中展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,则说明它们可以搭配使用.虚拟机所处的区域则表示它是属于新生代还是老年代收集器. 7种:serial收集器.parnew收集器.parallel scavenge收集器.serial  old 收集器.pa

JVM学习(4)——全面总结Java的GC算法和回收机制---转载自http://www.cnblogs.com/kubixuesheng/p/5208647.html

俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及到的知识点总结如下: 一些JVM的跟踪参数的设置 Java堆的分配参数 -Xmx 和 –Xms 应该保持一个什么关系,可以让系统的性能尽可能的好呢?是不是虚拟机内存越大越好? Java 7之前和Java 8的堆内存结构 Java栈的分配参数 GC算法思想介绍 –GC ROOT可达性算法 –标记清除 –标记压缩 –复制算法 可触及性含义和在Java中的体现 finalize方法理解 Java的强引用,软引用,弱引用,虚引用 GC

46张PPT讲述JVM体系结构、GC算法和调优

本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传至Github(点此下载),另外良心推荐阅读<深入理解Java虚拟机JVM高级特性与最佳实践.pdf>(点此下载).

关于JVM常用的GC算法

[Author]: kwu 关于GC(Garbage Collection)的算法,常用的有以下几种: 1.引用计数法 1) 老牌垃圾回收算法,通过引用计算来回收垃圾.引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1.只要对象A的应用计数器的值为0,则对象A就不可能再被使用. 使用引用计数法的语言: Micsoft COM ActionScript3 Python 2) 引用计数法的问题: 引用和去引用伴随加法和减法,影响

JVM GC算法 CMS 详解(转)

前言 CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求 大于对吞吐量的要求,能够承受垃圾回收线程和应用线程共享处理器资源,并且应用中存在比较多的长生命周期的对象的应用.CMS是用于对tenured generation的回收,也就是年老代的回收,目标是尽量减少应用的暂停时间,减少full gc发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清

深入JVM《四》 GC算法与种类

一.GC的概念 Garbage Collection 垃圾收集. 1960年 List 使用了GC. Java中,GC的对象是堆空间和永久区. 二. GC算法 1. 引用计数法(没有被java采用,在python中有) 老牌垃圾回收算法. 通过引用计算来回收垃圾. 引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1.只要对象A的引用计数器的值为0,则对象A就不可能再被使用. 问题: 1.引用和去引用伴随加法和减法,影响性能

JVM垃圾回收(四)- GC算法:实现(1)

GC算法:实现 上面我们介绍了GC算法中的核心概念,接下来我们看一下JVM里的具体实现.首先必须了解的一个重要的事实是:对于大部分的JVM来说,两种不同的GC算法是必须的,一个是清理Young Generation的算法,另一种是清理Old Generation的算法. 在JVM里有各种各样的这种内置算法,如果你没有特别指定GC算法,则会使用一个默认的.适应当前平台(platform-specific)的算法.接下来我们会解释每种算法的工作原理. 下面的列表提供了一个快速的预览,关于哪些算法可能

深入探究jvm之GC的算法及种类

一.GC基本概念 GC(Garbage Collection)垃圾收集,1960年最早在List中使用.在Java中GC回收的对象是堆空间和永久区,可以有效避免程序员人为造成内存泄漏问题.将堆空间和永久区没有作用的对象进行释放和回收. 二.GC算法 1.引用计数法: 是一种老牌的垃圾回收算法,通过引用计算来回收垃圾,被COM.ActionScript3.Python所使用. 引用计数法的实现很简单,对于一个对象A,只要有任何一个对象引用了A,那么A的引用计数器就会+1,当引用失效时,引用计数器就