垃圾回收算法

标记清除法

先标记出需要回收的对象,然后一次性回收。缺点:会产生内存碎片,并且效率也不高。

标记压缩法

先标记出需要回收的对象,然后让存活对象向一端移动,移动的过程中进行回收辣鸡。避免了内存碎片问题。

复制算法

把内存划分出相等的两块,每次只用其中一块。当一块用完了,就将还存活的对象移动到另一块内存上,然后把辣鸡清理掉。内存分配不用来考虑碎片问题,只需要顺序分配即可。缺点:总有一块内存闲着没事干。

为了形象生动可爱,我画了个图

..

垃圾回收器

串行收集器

串行辣鸡收集器只用一个单线程做所有工作,其内存占用空间大小也是所有辣鸡收集器里最低的。

  • 新生代辣鸡回收使用复制算法
  • 老年代使用标记压缩算法

并行收集器

并行收集器相对于串行收集器,使用了多线程来完成辣鸡回收的工作,但是同样也需要Stop-The-World。新生代和老年代的回收都是并行的。

(历史:刚引入的时候,新生代使用多线程,而老年代则是单线程进行辣鸡回收。随着堆的尺寸和老年代对象的数量和大小不断增长,老年代辣鸡回收的时间不断变长,增加了一个多线程的老年代收集器和多线程的新生代收集器同时使用的方式,由此得到了增强的并行辣鸡收集器)

  • -XX:+UseParallelGC  新生代使用并行收集器,老年代使用串行收集器
  • -XX:+UseParallelOldGC  新生代和老年代都使用并行收集器
  • 新生代使用复制算法
  • 老年代使用标记压缩算法

CMS收集器(Concurrent Mark Sweep)

在CMS辣鸡回收中,新生代的回收与并行辣鸡收集器很类似。它们是多线程的并且会使应用程序线程暂停。主要区别在于老年代的收集上。

CMS做辣鸡回收的时候与应用线程同时进行,除了少数的相对短暂的GC同步暂停,可以说是大多数情况是并发进行的。

CMS老年代收集活动从初始标记开始,这个阶段标记根可以直接关联到的对象,这个阶段是要暂停应用线程的。之后进入并发标记阶段,这个阶段标记所有对象,和应用线程一同运行。接着,进入重新标记阶段,这个阶段主要处理初始标记,并发标记过程中可能错过的对象,这个阶段是要暂停应用线程的。最后,并发清除启动,释放所有死亡对象所占用的空间。

  • 挑战1:要在应用消耗完Java的可用堆之前完成并发收集工作,因此选择一个合适的时机来启动这个并发收集工作尤为重要。
  • 挑战2:处理老年代中的空间碎片。如果老年代中空间碎片太小,无法容纳刚晋升上来的对象,因为CMS并发收集循环中并不执行压缩,所以可能导致CMS回过来使用串行GC,触发一次full收集,导致一个漫长的暂停。
  • 老年代主要使用标记清除算法。清理碎片显得很重要。
  • -XX:+UseCMSCompactAtFullCollection   垃圾收集完成后,进行一次内存碎片整理
  • -XX:CMSFullGCsBeforeCompaction  回收一定次数后,压缩一次内存

JDK 8中两个主要的并发收集器:
  并发标记扫描(CMS)收集器:此收集器适用于喜欢较短垃圾收集暂停且可以与垃圾收集共享处理器资源的应用程序。
  Garbage-First垃圾收集器:这种服务器式收集器适用于具有大内存的多处理器机器。它以高概率满足垃圾收集暂停时间目标,同时实现高吞吐量。

G1收集器(Garbage First)

G1把Java堆拆成一系列分区,这样的话,在某一个时间段内,大部分辣鸡回收只在一个区内而不是整个堆中进行。区域大小可以从1 MB到32 MB不等,具体取决于堆大小。目标是不超过2048个分区。伊甸区,幸存区和老年代是这些地区的逻辑集合,并不是连续的。

一个新概念:新生代不再是一个连续内存块,一个分区既可以变成新生代,也可以变成老年代。

堆被划分为一组大小相同的堆区域,每个区域都是一个连续的虚拟内存区域。G1执行一个并发全局标记阶段,以确定整个堆中对象的活性。

标记阶段完成后,G1知道哪些区域大部分是空的。它首先收集这些区域,这通常会产生大量的自由空间。这就是为什么这种垃圾收集方法被称为Garbage-First。

G1将对象从堆的一个或多个区域复制到堆上的单个区域,并且在此过程中压缩并释放内存。这个过程是多线程执行,以减少暂停时间并提高吞吐量。因此,随着每次垃圾收集,G1不断努力减少碎片。这超出了以前两种方法的能力->CMS(Concurrent Mark Sweep)垃圾收集不进行压缩。并行压缩仅执行整堆压缩,这会导致相当长的暂停时间。

所有Eden区+幸存区=新生代

..

新生代的收集和前面的没啥区别,都要暂停应用线程。老年代比CMS的老年代收集还要与众不同。↓↓

一个G1并发周期包含:初始标记、并发根分区扫描、并发标记、重新标记和清除。

在G1中,一旦达到内存堆的占用阈值[yu zhi],一次并发stop-the-world方式的初始标记阶段就会被安排执行,在此阶段标记所有GC根,根是对象图的起点。这个阶段会跟着下一次新生代收集同时进行。然后进入并发根分区扫描,扫描和跟踪survivor分区里所有对象的引用,唯一的限制是在下一次GC前必须先完成扫描,因为一次新的GC会产生一个新的存活对象集合,它跟初始标记的存活对象是有区别的。

然后进入并发标记阶段,标记老年代中所有存活对象。当并发标记阶段结束,并行stop-the-world的重新标记阶段就被启动,标记那些因为在标记阶段同时执行的应用线程导致产生的错过的对象。重新标记结束,就执行清除阶段,优先回收没有任何存活对象的分区,然后把每个收集过辣鸡的分区中的存活对象转移到一个可用分区中,一旦存活对象被转移,那么这个分区(新生代或者老年代)就可以被回收为可用分区。

G1最大的暂停时间来源于 新生代收集和混合收集(新生代和老年代一起)

JVM 辣鸡回收的更多相关文章

  1. GO的GC辣鸡回收(一)

    用户程序通过内存分配器(Allocator)在堆上申请内存,而垃圾收集器(Collector)负责回收堆上的内存空间,内存分配器和垃圾收集器共同管理程序中的堆内存空间. 基本概念 垃圾分类 语义垃圾: ...

  2. JVM的垃圾回收机制详解和调优

    JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都 ...

  3. jvm的垃圾回收算法

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

  4. 03 JVM的垃圾回收机制

    1.前言 理解JVM的垃圾回收机制(简称GC)有什么好处呢?作为一名软件开发者,满足自己的好奇心将是一个很好的理由,不过更重要的是,理解GC工作机制可以帮助你写出更好的Java程序. 在学习GC前,你 ...

  5. JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)

     相信和小编一样的程序猿们在日常工作或面试当中经常会遇到JVM的垃圾回收问题,有没有在夜深人静的时候详细捋一捋JVM垃圾回收机制中的知识点呢?没时间捋也没关系,因为小编接下来会给你捋一捋. 一. 技术 ...

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

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

  7. 扒一扒JVM的垃圾回收机制,下次面试你准备好了吗

      相信和小编一样的程序猿们在日常工作或面试当中经常会遇到JVM的垃圾回收问题,有没有在夜深人静的时候详细捋一捋JVM垃圾回收机制中的知识点呢?没时间捋也没关系,因为小编接下来会给你捋一捋. 一. 技 ...

  8. JVM的垃圾回收机制

    JVM的垃圾回收机制:(GC通过确定对象是否被活动对象引用来确定是否收集该对象.) 1.触发GC(Garbage Collector)的条件. (1.GC在优先级最低的线程中运行,在未运行的线程中进行 ...

  9. Java技术专题之JVM逻辑内存回收机制研究图解版

    一.引言 JVM虚拟机内存回收机曾迷惑了不少人,文本从JVM实现机制的角度揭示JVM内存回收的原理和机制. 一.Java平台逻辑架构 二.JVM物理结构 通过从JVM物理结构图我们可以看到: 1.JV ...

随机推荐

  1. Operation not allowed on a unidirectional dataset错误?

    关于网友提出的“ Operation not allowed on a unidirectional dataset错误?”问题疑问,本网通过在网上对“ Operation not allowed o ...

  2. php重定向http请求

    302  临时重定向 301  永久重定向     (  302 和 301  的区别主要在于搜索引擎,搜索引擎一般不会抓取临时重定向的页面  ) 301 和302 适用于 普通的GET 请求: 如果 ...

  3. Django中Form组件的使用

    Form介绍 HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入 ...

  4. html input 禁止输入中文

    <input type="text" class="tel" onkeyup="value=value.replace(/[\u4e00-\u9 ...

  5. pycharm pip 源修改以及包管理(转载)

    转载自(https://www.u3v3.com/ar/1352) pycharm下如何将默认的pip源改成国内能快速访问的源, 以及如何进行包管理 pycharm 是一款进行python项目开发的利 ...

  6. [IOI2018]机械娃娃——线段树+构造

    题目链接: IOI2018doll 题目大意:有一个起点和$m$个触发器,给出一个长度为$n$的序列$a$,要求从起点出发按$a$的顺序经过触发器并回到起点(一个触发器可能被经过多次也可能不被经过), ...

  7. 洛谷p1586四方定理题解

    题目 这个题的本质是动态规划中的背包问题. 为什么会想到背包呢. 因为往往方案数不是排列组合就是递推或者是dp,当然还有其他的可能.我们可以把一个数的代价当成这个数的平方,价值就是一个方案数.由于这个 ...

  8. 「Splay」区间翻转

    传送门:>Here< 解法分析 用splay来维护这个序列. 一直没有搞明白的是,这里的splay的节点究竟维护的是什么?是权值吗?肯定不是,因为区间是会翻转的,如果维护权值的话很快平衡树 ...

  9. 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT

    题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...

  10. 【CodeForces 717C】Potions Homework

    BUPT 2017 summer training (for 16) #1G 题意 每个人有一个懒惰值,每个任务有个难度,一开始每个人的任务和懒惰值都为\(a_i\),完成任务时间是懒惰值乘以难度,现 ...