java虚拟机学习-深入理解JVM(1)
java虚拟机学习-慢慢琢磨JVM(2)
java虚拟机学习-慢慢琢磨JVM(2-1)ClassLoader的工作机制
java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)
java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
java虚拟机学习-JVM调优总结(5)
java虚拟机学习-JVM调优总结(6)
java虚拟机学习-JVM调优总结-基本垃圾回收算法(7)
java虚拟机学习-JVM调优总结-垃圾回收面临的问题(8)
java虚拟机学习-JVM调优总结-分代垃圾回收详述(9)
java虚拟机学习-JVM调优总结-典型配置举例(10)
java虚拟机学习-JVM调优总结-新一代的垃圾回收算法(11)
java虚拟机学习-JVM调优总结-调优方法(12)

垃圾回收的瓶颈

传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限。但是他无法解决的一个问题,就是Full GC所带来的应用暂停。在一些对实时性要求很高的应用场景下,GC暂停所带来的请求堆积和请求失败是无法接受的。这类应用可能要求请求的返回时间在几百甚至几十毫秒以内,如果分代垃圾回收方式要达到这个指标,只能把最大堆的设置限制在一个相对较小范围内,但是这样有限制了应用本身的处理能力,同样也是不可接收的。

分代垃圾回收方式确实也考虑了实时性要求而提供了并发回收器,支持最大暂停时间的设置,但是受限于分代垃圾回收的内存划分模型,其效果也不是很理想。

为了达到实时性的要求(其实Java语言最初的设计也是在嵌入式系统上的),一种新垃圾回收方式呼之欲出,它既支持短的暂停时间,又支持大的内存空间分配。可以很好的解决传统分代方式带来的问题。

增量收集的演进

增量收集的方式在理论上可以解决传统分代方式带来的问题。增量收集把对堆空间划分成一系列内存块,使用时,先使用其中一部分(不会全部用完),垃圾收集时把之前用掉的部分中的存活对象再放到后面没有用的空间中,这样可以实现一直边使用边收集的效果,避免了传统分代方式整个使用完了再暂停的回收的情况。

当然,传统分代收集方式也提供了并发收集,但是他有一个很致命的地方,就是把整个堆做为一个内存块,这样一方面会造成碎片(无法压缩),另一方面他的每次收集都是对整个堆的收集,无法进行选择,在暂停时间的控制上还是很弱。而增量方式,通过内存空间的分块,恰恰可以解决上面问题。

Garbage Firest(G1)

这部分的内容主要参考这里,(http://www.blogjava.net/BlueDavy/archive/2009/03/11/259230.html),这篇文章算是对G1算法论文的解读。我也没加什么东西了。

目标

从设计目标看G1完全是为了大型应用而准备的。

支持很大的堆

高吞吐量

--支持多CPU和垃圾回收线程

--在主线程暂停的情况下,使用并行收集

--在主线程运行的情况下,使用并发收集

实时目标:可配置在N毫秒内最多只占用M毫秒的时间进行垃圾回收

当然G1要达到实时性的要求,相对传统的分代回收算法,在性能上会有一些损失。

算法详解

G1可谓博采众家之长,力求到达一种完美。他吸取了增量收集优点,把整个堆划分为一个一个等大小的区域(region)。内存的回收和划分都以region为单位;同时,他也吸取了CMS的特点,把这个垃圾回收过程分为几个阶段,分散一个垃圾回收过程;而且,G1也认同分代垃圾回收的思想,认为不同对象的生命周期不同,可以采取不同收集方式,因此,它也支持分代的垃圾回收。为了达到对回收时间的可预计性,G1在扫描了region以后,对其中的活跃对象的大小进行排序,首先会收集那些活跃对象小的region,以便快速回收空间(要复制的活跃对象少了),因为活跃对象小,里面可以认为多数都是垃圾,所以这种方式被称为Garbage First(G1)的垃圾回收算法,即:垃圾优先的回收。

回收步骤:

初始标记(Initial Marking

G1对于每个region都保存了两个标识用的bitmap,一个为previous marking bitmap,一个为next marking bitmap,bitmap中包含了一个bit的地址信息来指向对象的起始点。

开始Initial Marking之前,首先并发的清空next marking bitmap,然后停止所有应用线程,并扫描标识出每个region中root可直接访问到的对象,将region中top的值放入next top at mark start(TAMS)中,之后恢复所有应用线程。

触发这个步骤执行的条件为:

G1定义了一个JVM Heap大小的百分比的阀值,称为h,另外还有一个H,H的值为(1-h)*Heap Size,目前这个h的值是固定的,后续G1也许会将其改为动态的,根据jvm的运行情况来动态的调整,在分代方式下,G1还定义了一个u以及soft limit,soft limit的值为H-u*Heap Size,当Heap中使用的内存超过了soft limit值时,就会在一次clean up执行完毕后在应用允许的GC暂停时间范围内尽快的执行此步骤;

在pure方式下,G1将marking与clean up组成一个环,以便clean up能充分的使用marking的信息,当clean up开始回收时,首先回收能够带来最多内存空间的regions,当经过多次的clean up,回收到没多少空间的regions时,G1重新初始化一个新的marking与clean up构成的环。

并发标记(Concurrent Marking

按照之前Initial Marking扫描到的对象进行遍历,以识别这些对象的下层对象的活跃状态,对于在此期间应用线程并发修改的对象的以来关系则记录到remembered set logs中,新创建的对象则放入比top值更高的地址区间中,这些新创建的对象默认状态即为活跃的,同时修改top值。

最终标记暂停(Final Marking Pause

当应用线程的remembered set logs未满时,是不会放入filled RS buffers中的,在这样的情况下,这些remebered set logs中记录的card的修改就会被更新了,因此需要这一步,这一步要做的就是把应用线程中存在的remembered set logs的内容进行处理,并相应的修改remembered sets,这一步需要暂停应用,并行的运行。

存活对象计算及清除(Live Data Counting and Cleanup

值得注意的是,在G1中,并不是说Final Marking Pause执行完了,就肯定执行Cleanup这步的,由于这步需要暂停应用,G1为了能够达到准实时的要求,需要根据用户指定的最大的GC造成的暂停时间来合理的规划什么时候执行Cleanup,另外还有几种情况也是会触发这个步骤的执行的:

G1采用的是复制方法来进行收集,必须保证每次的”to space”的空间都是够的,因此G1采取的策略是当已经使用的内存空间达到了H时,就执行Cleanup这个步骤;

对于full-young和partially-young的分代模式的G1而言,则还有情况会触发Cleanup的执行,full-young模式下,G1根据应用可接受的暂停时间、回收young regions需要消耗的时间来估算出一个yound regions的数量值,当JVM中分配对象的young regions的数量达到此值时,Cleanup就会执行;partially-young模式下,则会尽量频繁的在应用可接受的暂停时间范围内执行Cleanup,并最大限度的去执行non-young regions的Cleanup。

展望

以后JVM的调优或许跟多需要针对G1算法进行调优了。

java虚拟机学习-JVM调优总结-新一代的垃圾回收算法(11)相关推荐

  1. JVM 调优实战--常见的垃圾回收算法及垃圾收集器组合

    什么是垃圾 C语言申请内存:malloc free C++: new delete c/C++ 手动回收内存 Java: new ? 自动内存回收,编程上简单,系统不容易出错,手动释放内存,容易出两种 ...

  2. JVM 调优系列之图解垃圾回收

    转载自  JVM 调优系列之图解垃圾回收 摘要: jvm必知系列,总结一些常见jvm回收机制,方便查阅 从这篇开始我们开始探讨一些jvm调优的问题.在jvm调优中一个离不开的重点是垃圾回收,当垃圾回收 ...

  3. JVM 调优实战--什么是垃圾回收及Java的自动垃圾回收GC

    什么是垃圾回收 程序的运行必然要申请内存资源,无效的对象资源如果不及时处理就会一直占用内存资源,最终将导致内存溢出,所以对内存资源的管理就变得非常重要了. C/C++语言的垃圾回收 在C/C++语言中 ...

  4. JVM调优:GC标记清除回收算法

  5. jvm性能调优 - 09白话新生代垃圾回收算法

    文章目录 Pre 复制算法的背景引入 一种不太好的垃圾回收思路 一个合理的垃圾回收思路 复制算法有什么缺点? 复制算法的优化:Eden区和Survivor区 新生代垃圾回收的各种"万一&qu ...

  6. JVM调优总结(6):新一代的垃圾回收算法

    原文出处: pengjiaheng 垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full G ...

  7. gateway 内存溢出问题_带你学习jvm java虚拟机 arthas/性能调优/故障排除/gc回收/内存溢出等...

    学完本课程,您将掌握: 内存溢出问题实战 CPU飙升问题实战 阿里巴巴Arthas在线诊断 Class字节详细拆解 手写类加载器.四种类加载器.双亲委托模型 对象创建.存储.访问.加载解析 性能调优. ...

  8. java虚拟机性能监控调优及原则

    转载自 https://www.cnblogs.com/thingk/p/6840585.html 摘抄 http://uule.iteye.com/blog/2114697 一.JVM内存模型及垃圾 ...

  9. 2022年字节跳动JAVA面试,JVM调优和调优,附面试题答案

    面试必问:JVM原理和调优(附面试题) 一.详解JVM内存模型 二.JVM中一次完整的GC流程是怎样的 三.GC垃圾回收的算法有哪些 四.简单说说你了解的类加载器 五.双亲委派机制是什么,有什么好处, ...

最新文章

  1. LVS详解及基于LVS实现web服务器负载均衡
  2. 网民网上购物决策时间延长
  3. iOS程序健壮性笔记
  4. python profile_python程序之profile分析
  5. js 中location 的学习
  6. php 如何 闭源,Linux_Debian如何安装闭源软件包有哪些方法,  在系统操作中,闭源软件 - phpStudy...
  7. nacos 整合Dubbo 多服务
  8. 【Elasticsearch】Elasticsearch 6.0中节省空间的改进
  9. Openwrt 软件安装源
  10. [Luogu 1730]最小密度路径
  11. App应用之提交到各大市场渠道
  12. UnityShader1:渲染流水线
  13. window创建计划自动启动服务器,WINDOWS2008计划任务无法启动
  14. UIKit 框架之UIAlertController
  15. python 有道翻译,python 简单的调用有道翻译
  16. window10家庭版设置Administrator用户net user administrator /active:yes
  17. DSPE-PEG-TAT,磷脂-聚乙二醇-靶向穿膜肽TAT,一种磷脂PEG肽
  18. JTAG/JLINK
  19. sql导出的身份证后几位是000
  20. cephfs:1 clients failing to respond to cache pressure原因分析

热门文章

  1. BaaS后端即服务 - 概念篇
  2. Spring Bean Scope 有状态的Bean 无状态的Bean
  3. 企业生产经营相关英文及缩写之(11)--Genenic 普通书写
  4. 新快现类似产品_小米全新折叠屏产品曝光,预计今年还有更多折叠屏产品亮相...
  5. 安装secureCRT提示sorry的解决办法
  6. 通过远程(vnc)无法打开qtcreator
  7. 字符串不替代_TI-Nspire 系列的字符串操作
  8. linux编译准备,Linux 下编译指南
  9. img=img%3e128 matlab,Matlab中一般的数值计算和使用
  10. python3.7.1使用_使用python3和pytorch1.7.1运行dface