文档章节

JVM垃圾收集

囚兔
 囚兔
发布于 2016/02/02 14:24
字数 1898
阅读 65
收藏 1
点赞 1
评论 0

目录

  1. 内存区域回顾
  2. 机制介绍
  3. 收集器介绍
  4. 调优

内存区域回顾

内存区域

垃圾回收机制

Java 对象生命周期

输入图片说明

根搜索算法

输入图片说明

输入图片说明 从GC Roots对象为起点,开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链时,此对象即为不可用,被判定为可回收对象。

标记过程

输入图片说明

垃圾收集算法

输入图片说明

堆内存区域划分

输入图片说明

垃圾收集器

输入图片说明

Serial - 新生代串行收集器

输入图片说明

  • 使用单线程进行垃圾回收
  • 独占式
  • 优点:实现简单,处理高效
  • 缺点:Stop The World
  • 使用-XX:+UseSerialGC指定使用
  • JVM在Client模式下默认垃圾收集器

ParNew - 新生代并行收集器

输入图片说明

  • 实现和Serial相同,仅将GC线程改成多线程
  • 优点:在多CPU情况下优于Serial
  • 缺点:Stop The World
  • -XX:+UseParNewGC
  • GC线程数,-XX:ParallelGCThreads,
  • 当CPU个数 < 8,ParallelGCThreads=CPU个数
  • 当CPU个数 > 8,ParallelGCThreads=3 + ( (5 * CPU个数) / 8)

Parallel Scavenge - 新生代并行收集器

线程模型和ParNew相同,区别在于Parallel Scavenge收集器的目标是达到一个可以控制的吞吐量

  • -XX:+UseParallelGC,指定使用
  • -XX:MaxGCPauseMillis,设置最大停顿时间,大于0的整数
  • -XX:GCTimeRatio,设置吞吐量大小,0~100整数,即运行用户代码时间 / 垃圾收集时间,默认值为99
  • -XX:+UseAdaptiveSizePolicy 自适应GC策略开关,在自适应模式下,新生代大小,survivor和eden区的比例、晋升老年代对象年龄等参数会被自动调整,以达到最合适的停顿时间,或最大吞吐量。

Serial Old - 老年代串行收集器

  • 使用标记-整理算法
  • 和Serial一样是串行独占式回收器
  • 可和Serial,ParNew 搭配使用
  • 缺点停顿时间可能会比较长

Parallel Old - 老年代并行收集器

  • 使用标记-整理算法
  • 和Parallel Scavenge一样是并行多线程收集器,也是关注于吞吐量
  • -XX:+UseParallelOldGC
  • 缺点停顿时间可能会比较长

CMS - 老年代并发收集器

输入图片说明 全称:Concurrent Mark Sweep

  • 基于标记-清除算法
  • 一种以获取最短停顿时间为目标的收集器

初始标记、重新标记仍然需要“Stop The world”。初始标记只标记GC Roots能直接关联到的对象,速度很快,时间很短。并发标记进行GC Roots Tracing,比较耗时。重新标记修正并发标记期间,程序继续运行导致的标记变动。由于整个过程中耗时最长的并发标记和并发清除阶段,GC线程可以与用户线程一起工作,总体上来说CMS是一款并发收集器,这也是CMS停顿时间较短的原因。

  • -XX:+UseConcMarkSweepGC 新生代使用并行收集器,老年代使用CMS + Serial Old
几个缺点
  • Cpu很敏感,并发阶段默认线程数是(CPU数量+3)/ 4 , CPU不足4个时,对程序性能影响较大
  • 无法处理浮动垃圾,清理阶段,用户线程继续运行会产生新的垃圾,可能出现“Concurrent Mode Failure”失败
  • CMS使用标记-清除算法,会产生大量空间碎片
优化方案
  • -XX:CMSInitiatingOccupancyFraction, 设置CMS收集器老年代使用多少空间会被激活,另外当出现“Concurrent Mode Failure”时,将临时启用Serial Old收集器来重新对老年代进行收集
  • -XX:+UseCMSCompactAtFullCollection, 开关参数,表示每次full GC后执行一次碎片整理。-XX:CMSFullGCsBeforeCompaction, 设置执行多少次full GC后,来一次碎片整理

垃圾收集参数总结

参考:http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

两种参数格式:

  • 开关参数,比如 -XX:+UseSerialGC,“+”代表开,“-”代表关
  • 值参数,比如 -XX:ParallelGCThreads=4
串行回收器(Serial + Serial Old)

-XX:+UseSerialGC 在新生代和老年代中使用串行收集器 -XX:SurvivorRatio 设置Eden与Survivor区大小比例 -XX:PretenureSizeThreshold 设置大对象直接进入老年代的阈值

并行GC(ParNew + CMS + Serial Old)
  • -XX:+UseParNewGC 在新生代使用并行收集器,默认老年代使用Serial Old,ParNew + Serial Old 已过期,不再推荐使用
  • -XX:+UseConcMarkSweepGC 新生代使用并行收集器,老年代使用CMS + Serial Old
  • -XX:ParallelGCThreads 设置用于垃圾回收的线程数
  • -XX:CMSInitiatingOccupancyFraction 设置CMS收集器在老年代空间被使用多少后触发, JDK7中默认为92%, CMSInitiatingOccupancyFraction = (100 - MinHeapFreeRatio) + (CMSTriggerRatio * MinHeapFreeRatio / 100)
  • -XX:+UseCMSCompactAtFullCollection 设置CMS收集器在完成垃圾收集后是否进行一次内存碎片整理,默认为true
  • -XX:CMSFullGCsBeforeCompaction 设定多少次CMS垃圾回收后,进行一次内存碎片整理,默认为0
  • -XX:+CMSClassUnloadingEnabled 允许对类元数据进行回收
  • -XX:CMSInitiatingPermOccupancyFraction 当永久代占用率达到这个百分比时,启用CMS回收(前提先开启CMSClassUnloadingEnabled)
并行GC(Parallel Scavenge + Parallel Old)
  • -XX:UseParallelGC 新生代使用Parallel Scavenge,server模式下默认开启
  • -XX:UseParallelOldGC 年老代使用Parallel Old, server模式下默认开启
  • -XX:ParallelGCThreads 设置用于垃圾回收的线程数
  • -XX:MaxGCPauseMillis 设置最大垃圾收集停顿时间
  • -XX:GCTimeRatio 设置吞吐量大小,它的值是一个0~100之间的整数,执行用户代码的时间 / 垃圾收集时间
  • -XX:+UseAdaptiveSizePolicy 打开自适应GC策略
  • -XX:+PrintAdaptiveSizePolicy 打印自适应分代大小调整信息
其他
  • -XX:MaxTenuringThreshold 设置对象进入老年代的年龄最大值,每一次Minor GC后,对象年龄加1,默认值15,使用ConcMarkSweep时默认6
  • -XX:+DisableExplicitGC 禁用显式GC,System.gc() 失效
  • -XX:+PrintGCDetails 显示GC日志详细信息
  • -Xloggc:<filename> 将GC日志输出到日志文件
  • -Xmx 堆最大大小
  • -Xms 堆初始大小
  • -Xmn 新生代大小,相当于NewSize和MaxNewSize固定为相同的值
  • -XX:NewSize 新生代初始大小
  • -XX:MaxNewSize 新生代最大大小
  • -XX:PermSize 永久代初始大小
  • -XX:MaxPermSize 永久代最大大小
  • -XX:+PrintFlagsFinal 打印最终的参数值
  • -XX:+PrintCommandLineFlags

内存分配和回收策略

  • 对象优先在Eden区分配
  • 大对象直接进入老年代, -XX:PretenureSizeThreshold, 设置大对象直接进入老年代的大小阈值。只在Serial GC 和ParNew GC时有效,尽量在程序中避免大对象的存在
  • 长期存活的对象进入老年代, -XX:MaxTenuringThreshold, 对象经历MinorGC的次数,默认为15,不一定非要到达这个年龄才进入老年代。
  • 空间分配担保

调优

GC日志收集参数

  • -verbose:gc
  • -XX:+PrintGCDetails
  • -XX:+PrintGCDateStamps 显示gc日志时间年月日时分秒
  • -XX:+PrintGCTimeStamps 显示gc日志距启动的时长
  • -Xloggc:gcfile
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:HeapDumpPath

GC日志解读

输入图片说明 Times: user - 用户态消耗的cpu时间 sys - 内核态消耗的cpu时间 real - 操作从开始到结束经过的墙钟时间

GC日志收集分析工具

  • jmap
  • jstat / jstatd
  • jconsole
  • jVisualVM

上面工具的都包含在jdk bin目录下

  • GCViewer

减少Full GC

  • 将新对象预留在新生代
  1. 增大新生代空间
  2. 增大survivor区大小,-XX:SurvivorRatio,默认值8
  3. 提高from区利用率 -XX:TargetSurvivorRatio, 默认值50
  • 防止永久代满导致full GC
  • 谨慎使用System.gc() // 堆外内存相关, -XX:+DisableExplicitGC --禁用

选择合适的垃圾收集器

吞吐量优先

使用ParallelGC + ParallelOldGC

降低停顿时间

使用ParNewGC + CMS,CMS对老年代的回收暂停时间远远小于ParallelOld

案例

见《jvm调优案例-xwiki吞吐量调优》

© 著作权归作者所有

共有 人打赏支持
囚兔

囚兔

粉丝 38
博文 76
码字总数 46066
作品 1
南京
程序员
《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

⋅ 05/05 ⋅ 0

面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb ⋅ 05/12 ⋅ 0

聊聊JAVA虚拟机中的垃圾收集器

前言 JAVA虚拟机的垃圾收集器是虚拟机内存的清道夫,它的存在让JAVA开发人员能将更多精力投入到业务研发上。了解垃圾收集器,并利用好这个工具,能更好的保障服务稳定性。这篇文章通过分析J...

lilugoodjob ⋅ 05/13 ⋅ 0

JAVA虚拟机 JVM 详细分析 原理和优化(个人经验+网络搜集整理学习)

JVM是java实现跨平台的主要依赖就不具体解释它是什么了 ,简单说就是把java的代码转化为操作系统能识别的命令去执行,下面直接讲一下它的组成 1.ClassLoader(类加载器) 加载Class 文件到内...

小海bug ⋅ 06/14 ⋅ 0

apache Tomcat 内存不够用?

  简介   Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,tomcat内存优化主要是对 tomcat 启动参数优化,我们可以通过修改tomcat 的启动脚本 catalina.sh(windows是catalina.ba...

linux运维菜 ⋅ 前天 ⋅ 0

JVM自动内存管理机制—读这篇就够了

之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾。这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享。 Java自动内...

java高级架构牛人 ⋅ 06/13 ⋅ 0

JVM汇总--jvm调优-命令篇

GC的最根本原因:垃圾收集器的工作就是清除Java创建的对象,垃圾收集器需要清理的对象数量以及要执行的GC数量均取决于已创建的对象数量。因此,为了使你的系统在GC上表现良好,首先需要减少创...

素雷 ⋅ 04/12 ⋅ 0

Java 面试知识点解析(三)——JVM篇

前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大部...

我没有三颗心脏 ⋅ 05/16 ⋅ 0

一篇简单易懂的原理文章,让你把JVM玩弄与手掌之中

jvm原理 Java虚拟机是整个java平台的基石,是java技术实现硬件无关和操作系统无关的关键环节,是java语言生成极小体积的编译代码的运行平台,是保护用户机器免受恶意代码侵袭的保护屏障。JVM...

烂猪皮 ⋅ 05/08 ⋅ 0

Java JVM 参数 -Xms -Xmx -Xmn -Xss调优总结

常见配置举例 1.堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制.32位系统 下,一般限制在1.5G~2G;6...

哲别0 ⋅ 05/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部