jvm垃圾收集算法

1、引用计数算法
每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。还有一个问题是如何解决精准计数。
这种方法现在已经不用了

2、根搜索算法
从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。不可达对象。

在java语言中,GC Roots包括:
虚拟机栈中引用的对象。
方法区中类静态属性实体引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI引用的对象。

jvm垃圾回收算法

1、复制算法(Copying)

  • 复制算法采用从根集合扫描,并将存活对象复制到一块新的,没有使用过的空间中,这种算法当控件存活的对象比较少时,极为高效,但是带来的成本是需要一块内存交换空间用于进行对象的移动。
  • 此算法用于新生代内存回收,从E区回收到S0或者S1

从根集合扫描、就是刚才说的GC-Roots 收集算法、从它开始查你的引用、如果没有被引用、开始执行算法、并将存活对象复制到一块新的、(S0或者S1)

2、标记清除算法

  • 标记-清除算法采用从根集合进行扫描,对存活的对象标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收,如图所示。
  • 标记-清除算法不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活对象比较多的情况下极为高效,但由于标记-清除算法直接回收不存活的对象,因此会造成内存碎片!

适合老生代去回收

标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端空闲空间移动,并更新对应的指针。
标记-整理算法是在标记清除算法的基础上,又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。

名词解释

1、串行回收
gc单线程内存回收、会暂停使有用户线程
2、并行回收
收集是指多个GC线程并行工作,但此时用户线程是暂停的;所以,Seral是串行的,Paralle收集器是并行的,而CMS收集器是并发的。
3、并发回收
是指用户线程与GC线程同时执行(不一定是并行,可能交替,但总体上是在同时执行的),不需要停顿用户线程(其实在CMS中用户线程还是需要停顿的,只是非常短,GC线程在另一个CPU上执行)

串行回收要区分好并行回收和并发回收的区别,这地方非常关键、在选择GC的过程中根据应用场景来选择

JVM常见垃圾回收器

上图是HotSpot里的收集器,中间的横线表示分代,有连线表示可以组合使用。

年轻代区域有
Serial 串行
ParNew 并发
Parallel Scavenge 并行
年老代区域有
CMS
Serial Old
Parallel Old
G1目前还不成熟 、适合年轻代和年老代

Serial 回收器(串行回收器)

是一个单线程的收集器,只能使用一个CPU或一条线程区完成垃圾收集;在进行垃圾收集时,必须暂停所有其它工作线程,直到收集完成。
缺点:Stop-The-World
优势:简单。对于单CPU的情况,由于没有多线程交互开销,反而可以更高效。是Client模式下默认的新生代收集器。

新生代Serial回收器
1、通过-XX:+UseSerialGC来开启
Serial New+Serial Old的收集器组合进行内存回收
2、使用复制算法。
3、独占式的垃圾回收。
一个线程进行GC,串行。其它工作线程暂停。
老年代Serial回收器
1、-XX:UseSerialGC来开启
Serial New+Serial Old的收集器组合进行内存回收
2、使用标记-压缩算法
3、串行的、独占式的垃圾回收器。
因为内存比较大的原因,回收比新生代慢

ParNew回收器(并行回收器)

并行回收器也是独占式的回收器,在收集过程中,应用程序会全部暂停。但由于并行回收器使用多线程进行垃圾回收,因此,在并发能力比较强的CPU上,它产生的停顿时间要短
于串行回收器,而在单CPU或者并发能力较弱的系统中,并行回收器的效果不会比串行回收器好,由于多线程的压力,它的实际表现很可能比串行回收器差。

新生代ParNew回收器

1、-XX:+UseParNewGC开启
新生代使用并行回收收集器,老年代使用串行收集器
2、-XX:ParallelGCThreads 指定线程数
默认最好与CPU数理相当,避免过多的线程数影响垃圾收集性能
3、使用复制算法。
4、并行的、独占式的垃圾回收器。

新生代Parallel Scavenge回收器

1、吞吐量优先回收器
关注CPU吞吐量,即运行用户代码的时间/总时间。比如:JVM运行100分钟,其中运行用户代码99分钟,垃圾回收1分钟。则吞吐量是99%,这种收集器能最高效率的利用CPU,适合运行后台运算
2、-XX:+UseParallelGC开启
使用Parallel Scavenge+Serial Old收集器组合回收垃圾,这也是Server模式下的默认值
3、-XX:GCTimeRation
来设置用户执行时间占总时间的比例,默认99,即1%的时间用来进行垃圾回收
4、-XX:MaxGCPauseMillis
设置GC的最大停顿时间
5、使用复制算法

老生代Parallel Old回收器

1、-XX:+UseParallelOldGC开启
使用Parallel Scavenge +Parallel Old组合收集器进行收集
2、使用标记整理算法。
3、并行的、独占式的垃圾回收器。

CMS(并发标记清除)回收器

运作过程分为4个阶段:
初始标记(CMS inital mark):值标记GC Roots能直接关联到的对象。
并发标记(CMS concurrent mark):进行GC RootsTracing的过程。
重新标记(CMS remark):修正并发标记期间用户程序继续运行而导致标记发生改变的那一部分对象的标记.

并发清除(CMS concurrent sweep):
其中标记和重新标记两个阶段仍然需要Stop-The-World,整个过程中耗时最长的并发标记和并发清除过程中收集器都可以和用户线程一起工作

CMS(并发标记清除)回收器

1、标记-清除算法
同时它又是一个使用多线程并发回收的垃圾收集器
2、-XX:ParalleCMSThreads
手工设定CMS的线程数量,CMS默认启动的线程数是(ParallelGCTherads+3)+3/4)
这是它的公式,一般情况下、对于IO密集型的 cpu的核数乘以2+1 ,CPU密集型的一般CPU的核数+1
3、-XX+UseConcMarkSweepGC开启
使用ParNew+CMS+Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现“Concurrent Mode Failure” 失败后的后备收集器使用.

失败以后就会触发Full GC 、位了避免这种情况发生、就要对它进行配置、触发Full GC有两种情况、promotion failed和concurrent mode failure
对于采用CMS进行老年代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能
会触发Full GC。
promotion failed是在进行Minor GC时,survivor space放不下、对象只能放入老年代,而此时老年代也放不下造成的;concurrent mode failure是在
执行CMS GC的过程中同时有对象要放入老年代,而此时老年代空间不足造成的(有时候“空间不足”是CMS GC时当前的浮动垃圾过多导致暂时性的空间不足触发Full GC)。
对应措施为:增大survivor space、老年代空间或调低触发并发GC的比率。

4、-XX:CMSInitiatingOccupancyFraction
设置CMS收集器在老年代空间被使用多少后触发垃圾回收器,默认值为68%,仅在CMS收集器时有效,-XX:CMSInitiatingOccupancyFraction=70

(一般情况为70%,设太高了可能会出现失败,设太低了、频繁, 只能去找一个比值、可以分析GC log、看是否符合你的要求 )

5、-XX:+UseCMSCompactAtFullCollection
由于CMS收集器会产生碎片,此参数设置在垃圾收集器后是否需要一次内存碎片整理过程,仅在CMS收集器时有效

6、-XX:+CMSFullGCBeforeCompaction
设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与UseCMSCompactAtFullCollection参数一起使用
7、-XX:CMSInitiatingPermOccupancyFraction
设置Perm Gen使用到达多少比率时触发,默认92%

JVM原理与深度调优(三)的更多相关文章

  1. JVM原理以及深度调优(二)

    JVM内存分配 内存分配其实真正来讲是有三种的.但对于JVM来说只有两种 栈内存分配: 大家在调优的过程中会发现有个参数是-Xss 默认是1m,这个内存是栈内存分配, 在工作中会发现栈OutOfMem ...

  2. JVM原理与深度调优(一)

    什么是jvm jvm是java虚拟机 运行在用户态.通过应用程序实现java代码跨平台.与平台无关.实际上是"一次编译,到处执行" 1.从微观来说编译出来的是字节码!去到哪个平台都 ...

  3. JVM原理与深度调优

    什么是jvm jvm是java虚拟机 运行在用户态.通过应用程序实现java代码跨平台.与平台无关.实际上是"一次编译,到处执行" 1.从微观来说编译出来的是字节码!去到哪个平台都 ...

  4. (转)JVM原理讲解和调优

    背景:jvm实际调优在面试时候经常被问到,所以有必要认真总结一番. 转自:JVM原理讲解和调优 四.JVM内存调优 首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存 ...

  5. JVM原理讲解和调优

    一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...

  6. Jvm原理剖析与调优之内存结构

    一些不得不说的概念 JVM JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机包括一套字节码指令集.一组寄存器.一个栈.一个 ...

  7. java JVM原理讲解和调优和gc

  8. 深入理解JVM虚拟机10:JVM常用参数以及调优实践

    转自http://www.rowkey.me/blog/2016/11/02/java-profile/?hmsr=toutiao.io&utm_medium=toutiao.io&u ...

  9. JVM基本配置与调优

    JVM基本配置与调优 JVM调优,一般都是针对堆内存配置调优. 如图:堆内存分新生代和老年代,新生代又划分为eden区.from区.to区. 一.区域释义 JVM内存模型,堆内存代划分为新生代和老年代 ...

随机推荐

  1. IdentityServer 部署踩坑记

    IdentityServer 部署踩坑记 Intro 周末终于部署了 IdentityServer 以及 IdentityServerAdmin 项目,踩了几个坑,在此记录分享一下. 部署架构 项目是 ...

  2. c语言 0与非0

    ------------恢复内容开始------------ 结论: 其它的编程语言中有布尔数据类型,并用百来表示逻辑真和逻辑假,C语言没有这个内置类度型,在C语言中真和假是用整型值来表示知的,0就表 ...

  3. (js描述的)数据结构[树结构1.1](11)

    1.树结构: 我们不能说树结构比其他结构都要好,因为每种数据结构都有自己特定的应用场景. 但是树确实也综合了上面的数据结构的优点(当然有点不足于盖过其他的数据结构,比如效率一般情况下没有哈希表高) 并 ...

  4. VSCode 初次写vue项目并一键生成.vue模版

    VSCode 写vue项目一键生成.vue模版 1.新建代码片段 文件-->首选项-->用户代码片段-->点击新建代码片段--取名vue.json 确定 2.配置快捷生成的vue模板 ...

  5. docker 相关操作

    docker-compose down //关闭所有容器 docker-compose up //开启所有容器 docker-compose restart //重启所有容器 单独更新某个容器时用脚本 ...

  6. linux升级python2.7到3.7.0

    1.下载python3.7.0压缩包在 wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz 2.解压缩 tar -zxvf Py ...

  7. day01-课后作业

    #1.写一个登陆的程序,最多登陆失败3次#2.输入账号 密码,如果登录成功,程序结束,提示 欢迎 xx 登录,今天的日期是 xx#3.登录失败,重新登陆#3.要判断输入是否为空,什么也不输入,输入空格 ...

  8. 【python实现卷积神经网络】激活函数的实现(sigmoid、softmax、tanh、relu、leakyrelu、elu、selu、softplus)

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  9. floyd三重循环最外层为什么一定是K

    Floyd算法为什么把k放在最外层? - 知乎 https://www.zhihu.com/question/30955032高票答案: 简单地总结一下:K没放在最外面一定是错的,但是在某些数据比较水 ...

  10. 数据结构和算法(Golang实现)(5)简单入门Golang-接口

    接口 在Golang世界中,有一种叫interface的东西,很是神奇. 一.数据类型 interface{} 如果你事前并不知道变量是哪种数据类型,不知道它是整数还是字符串,但是你还是想要使用它. ...