⑴背景

Java堆和方法区实现类所需内存是不一样的,每个方法的多分支需要的内存也可能不一样,我们只有在运行期间才能制动创建哪些对象。这部分内存分配与回收都是动态的,而垃圾回收器所关注的就是这些这部分内存。

⑵基本垃圾回收算法

①引用计数法:给每个对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1,当引用失效时,计数器就减1,任何时刻计数器为0的对象是不可能被使用的。

引用计数法简单易实现,但判定效率也很高,在大部分情况下式不错的算法。但主流Java虚拟机都没有使用引用计数器来管理内存,主要原因是他很难解决对象之间的循环引用问题

例如:ObjA.instance = ObjB,ObjB.instance = ObjA,除此之外这两个对象再无其他引用。实际上这两个对象没有别其他对象应用,但是引用计数器无法通知GC来回收它们。

②可达性分析:在Java中是使用可达性分析来判定对象是否存活。算法思路就是通过一系列称为“GC Roots”的队形作为起点,从这些节点向下搜索搜索所走的路径称为“引用链”,当一个对象

到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

如图:

③标记-清除算法:标记-清楚算法分为两个阶段,首先标记处所需的回收对象,在标记完成之后统一回收所有标记的对象,后面的算法都是基于该算法进行改进。该算法有两大不足之处:一是效率低,标记与清除的两个过程效率不高;二是空间问题,标记清除之后会产生大量的不连续内存碎片,空间碎片过多会导致以后程序运行时需要分配较大对象时,无法找到足够的连续内存,而不得不提前触发一次垃圾收集动作。

如图(图片来自网络):

④复制算法:复制算法常用于新生代。将可用内存按容量划分为大小相等的两块,每次使用其中一块,当这一块用完之后,仍存活的对象赋值到另一块上,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个搬去进行内存回收,内存分配时不需要考虑内存不连续,碎片的情况,只需要按顺序分配内存即可。但是该算法的代价是内存缩小为原来的一半。属于用空间换时间。

在新生代的对象中98%是“朝生夕死”的,所以并不需要按照1:1的比例划分空间,而是将内存分为一块较大的Eden空间和两块较小的Suvivor空间,每次使用Eden和其中一个Survivor,当回收时,将Eden和Suvivor中还存活的对象一次性地复制到另一块Survivor空间上,然后清楚掉Eden和刚才用过的Survivor空间。

⑤标记-整理:标记-整理算法常用于老年代,如果在内存中如果对象的存活率较高,使用复制算法效率就会非常低下。于是根据老年代的特点出现了“标记-整理”算法,其标记过程与“标记-清除”算法一样,后续步骤不是直接就对可回收对象进行清除,而是让所有存活的对象移动到一端,然后直接清理掉边界以外的内存。

如图(图片来自网络):

⑥分代收集算法:根据对象存活周期分为新生代和老年代,然后根据各自年代特点使用不同算法。在新生代中,每次垃圾收集时发现有大批对象死去,存货量较小,这时候使用复制算法就非常合适。在老年代中,对象的存活率较高,使用复制算法显然不划算,这时候就选择采用“”“标记-整理”算法去实现内存回收。

⑶垃圾收集器

HotSpot虚拟机垃圾收集器(图片来自网络)

①Serial收集器:该收集器是一个单线程的收集器,只会使用一个CPU或一条收集线程去完成垃圾收集,而且在进行垃圾收集时,其他工作线程都必须暂停。

②ParNew收集器:ParNew是Serial收集器的多线程版本。

ParNew收集器是Server模式下的虚拟机中首选的新生代收集器,其中一个与性能无关但很重要的原因是,除了Serial收集器外,目前只有它能够与CMS收集器配合工作,在单CPU环境中效果不比Serial,但但当CPU非常多的环境下,ParNew的优势就体现出来了。

③ CMS收集器:以获取最短回收停顿时间为目标的收集器,CMS收集器基于“标记-清除”算法实现。

过程分为4个部分:

Ⅰ 初始标记:初始标记仅仅只是标记GC Roots所能够关联到的对象(可达性分析)

Ⅱ 并发标记:根搜索(GC Roots Tracing)算法基本原理是:GCRoot对象作为起始点(根)。如果从根到某个对象是可达的,则该对象称为“可达对象”(存活对象,不可回收对象)。

Ⅲ 重新标记:重新标记阶段是为了修正并发标记期间因用户程序运作而导致标记产生变动的那一部分对象的标记记录。(边打扫卫生边仍纸屑)

Ⅳ 并发清除:并发将可回收内存全部回收。

其中需要“Stop The World”的有Ⅰ,Ⅲ过程

CMS缺点:

Ⅰ.CPU资源非常敏感,在面向并发程序时,CMS虽然不会导致用户线程停顿,但仍然会因为并发标记或并发清除占用了部分线程,导致应用程序变慢,总吞吐量降低。

Ⅱ.CMS无法处理浮动垃圾,由于CMS并发清理阶段用户线程仍在运行着,伴随程序运行,自然还会有新的垃圾不断产生,这一部分垃圾出现在标记标记过程之后,CMS无法在当次集中处理它们,只能留到下一次GC再处理.

Ⅲ.CMS基于“标记-清除”算法,该算法会产生大量的空间碎片,会出现老年代空间剩余,但无法找到连续的空间去分配当前对象,就必须提前触发一次Full GC.

④G1收集器:G1收集器是目前前沿收集器技术之一,到了JDK7u4才达到了商用程度

G1收集器所具备的特点:

Ⅰ.并发与并行:G1具有CMS一样多线程操作能力,G1能利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短Stop-The-World停顿时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然能够通过并发方式让Java线程继续执行。

Ⅱ.分代收集:G1不需要其他收集器配合就能够独立管理整个GC堆,但他能够使用不同的方式去处理新创建对象和已存活一段时间对象、熬过多次的旧对象都有自己的处理方法。

Ⅲ.空间整合:CMS基于“标记-清除”,缺点是出现许多不连续内存,而G1则基于“标记-整理”,从局部(两个Region)上看基于“复制”算法,G1运行期间不会产生大量空间碎片,收集后能提供规整的可用内存空间,在分配大对象时不会由于找不到可用的连续内存而出发下一次GC。

Ⅳ.可预测停顿:G1与CMS不同,G1除了追求低停顿以外,还能建立可预测的停顿时间模型。

更详细:http://blog.csdn.net/renfufei/article/details/41897113

Java虚拟机之GC的更多相关文章

  1. java虚拟机(十三)--GC调优思路

    GC调优对我们开发人员来说,如果你想要技术方面一直发展下去,这部分内容的了解是必不可少的,jvm对于工作.面试来说都很重要,GC调优的问题 更是重中之重,因为是对你jvm学习内容的实践,知识只有应用实 ...

  2. java虚拟机之GC(转)

    垃圾回收主要内容: 1. 那些内存需要回收? 2. 什么时候回收? 3. 如何回收? 垃圾回收主要针对运行时数据区那些区域? 运行时数据区的线程私有区域有:虚拟机栈,本地方法栈,程序计数器等: 栈中的 ...

  3. Java 虚拟机枚举 GC Roots 解析

    JVM 堆内存模型镇楼. 读<深入理解 Java 虚拟机>第三章GC算法,关于 GC Roots 枚举的段落没说透彻,理解上遇到困惑.因此对这点进行扩展并记录,发现国内各种博客写来写去都是 ...

  4. java虚拟机(十一)--GC日志分析

    GC相关:java虚拟机(六)--垃圾收集器和内存分配策略 java虚拟机(五)--垃圾回收机制GC 打印日志相关参数: -XX:+PrintGCDetails -XX:PrintGCTimestam ...

  5. 深入理解java虚拟机,GC参考手册

    深入理解java虚拟机 一.<深入理解Java虚拟机> 1.第2章 Java内存区域与内存溢出异常 2.第3章 垃圾收集器与内存分配策略 3.第4章 虚拟机性能监控与故障处理工具 4.第5 ...

  6. Java虚拟机:GC算法深度解析

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 在前面的文章里介绍了可达性分析算法,它为我们解决了判定哪些对象可以回收的问题,接下来就该我们的垃圾收集算法出场了.不同的垃圾收集算法有各自 ...

  7. 深入理解Java虚拟机,gc输出参数

    https://blog.csdn.net/qq_21383435/article/details/80702205

  8. java虚拟机(十二)--可视化工具分析GC日志

    在上篇博客中,我们学习了Parallel.CMS.G1三种垃圾收集器的日志格式,本次我们通过工具去分析日志,会更加的直观 日志格式博客地址:java虚拟机(十一)--GC日志分析 GCeasy: 这是 ...

  9. Java虚拟机-垃圾收集器

    垃圾收集器(Garbage Collection, GC)的诞生引导出了三个问题: 哪些内存需要回收? 什么时候回收? 如何回收? 对于线程独占的三个区域(程序计数器.虚拟机栈.本地方法栈)不用过多的 ...

随机推荐

  1. 应对不同格式 轻松转换PDF、WORD、PPT、TXT常用文件

    PDF.WORD.PPT.TXT,不同格式的文件是不是弄得你眼花缭乱?如何巧妙地将它们相互转换?你不会还在键盘上傻傻地一个字一个字敲吧?教你不同文件格式间的转换方式,轻松几键便能大功告成.职场之上,你 ...

  2. ASP.NET Core轻松入门之Middleware管道模型

    Middleware指的是微软的的asp.net core的管道模型.其原理可以用微软官方的下图展示: 原理如上图,随着Request的发起,HttpContext会经历多个管道处理(图中的箭头游走方 ...

  3. 使用 github 做代码管理,知道这些就够了

    只要掌握了下面的常用命令,基本上用使用 github 就没有问题.github 有两种认证方式,一种是通过 ssh 私钥的方式,一种通过 https 的账号名和密码.ssh 方式需要创建本地秘钥并且添 ...

  4. 纯CSS实现二级导航下拉菜单--css的简单应用

    思想:使用css的display属性控制二级下拉菜单的显示与否.当鼠标移动到一级导航菜单的li标签时,显示二级导航菜单的ul标签.由于实现起来比较简单,所以在这里直接给出了参考代码. 1.纯CSS二级 ...

  5. 又把JDK改回JDK1.8的过程

    我已经在崩溃的边缘. 先在控制面板卸载9.0.4,非常好,卸的干干净净的. 然后继续卸载9.0.1,也很好,卸的很干净. 命令行: 安装JDK1.8 装完了,去配环境变量: 4个环境变量都配齐了. J ...

  6. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  7. [CF932E]Team Work & [BZOJ5093]图的价值

    CF题面 题意:求\(\sum_{i=0}^{n}\binom{n}{i}i^k\) \(n\le10^9,k\le5000\) 模\(10^9+7\) BZOJ题面 题意:求\(n*2^{\frac ...

  8. Android Foreground Service (前台服务)

    一.如何保活后台服务 在Android Services (后台服务) 里面,我们了解了Android四大组件之一的Service,知道如何使用后台服务进行来完成一些特定的任务.但是后台服务在系统内存 ...

  9. Openflow简介和安装

    搞网络研究的,跟踪斯坦福stanford大学的研究就很重要. 因为思科CISCO与斯坦福的渊源太深了.被誉神雕侠侣的思科创始人Sandy Lerner夫妇,一个在计算机学院,一个在商学院. 最近去看了 ...

  10. angularjs 缓存详解

    一.什么是缓存 一个缓存就是一个组件,它可以透明地存储数据,以便未来可以更快地服务于请求. 缓存能够服务的请求越多,整体系统性能就提升得越多. 二.Angular 中的缓存 2.1 $cacheFac ...