Java GC调优(下)
4.Sun HotSpot 垃圾回收器
概述
当永久代和旧生代出发GC时,除CMS外都会发生Full GC
- 首先按照 新生代配置的GC,发生Mintor GC
- 再按照旧生代配置的GC,对旧生代和永久代GC
- 若JVM 对Mintor GC后可能会发生晋升失败,则直接采用旧生代配置的GC对Young,old,Perm进行GC.
一些术语解释
图1
图2
新生代可用GC
均使用复制算法,原理一样。
- 拷贝eden和from中的存活对象到to中;
- 部分对象由于某些原因直接晋升到old中;
- 清空eden、from,from和to交换下身份,直到下一次GC发生
分配对象时,Eden区内存不足时触发
Serial Copying
特性
serial (串行),stop-the-world
适用场景
- 单cpu,新生代小,对暂时时间要求不高的
- client级别或32位window上默认选择
直接分配到old的规则
- 对象大小超过eden space
- 大对象(PretenureSizeThreadold)晋升old
晋升规则
- 经历多次Mintor GC 仍存活的对象
- To Survivor满或空间不足,直接晋升
ParNew
特性
- 可以认为是Serial Copying的多线程版本
- 可搭配CMS(Concurrent Mark Sweep)
- 不可搭配Parallel old
ParNew Scavenge
特性
- Parallel Stop-the-world
- 并行默认参数
cpu核数<=8:=cpu核数
cpu核数>8:=(3+cpu核心*5)/8
- 调节策略(GC Ergonomics)
会根据Mintor GC频率、时间动态的调整Eden\S0\S1大小,可以消除特性(-XX:UseAdaptiveSizePolicy)
适用场景
- 多cpu,暂停较短的应用
- server级别,2核2G 机器上的默认选择
直接分配到old的规则
- 在TLAB和Eden上分配失败,对象大小大于Eden的一半
- PretenureSizeThreadold 参数无效
晋升规则
- 经历多次Mintor GC仍存活对象
- To Survivor内存满的对象直接晋升
旧生代可用的GC
Serial old(Serial MSC)
特性
- Serial、Stop-the-world
- 使用算法Mark-Sweep-Compact
- 由于是单线程,可能造成GC暂停时间可能会很长,可使用-XX:PrintGCApplicationStoppedTime查看暂停时间
适用场景
- client级别或32位window上默认选择
Parallel old(Parallel compacting)
特性
- Parallel、Stop-the-world
- 使用算法:Mark-compact
算法描述图:
适用场景
- 多cpu,暂停较短的应用
- server级别,2核2G 机器上的默认选择
CMS(Concurrent Mark Sweep)
特性
- Parallel、Concurrent
- 使用算法:Mark-sweep
算法描述图:
- 缩短GC暂停时间,比较复杂,GC总时间增加
- 默认并发数=(处理器核心数+3)/4,也可以用-XX:ParallelCMSThreads=2
- Prem Generation也可以启用CMS,-XX:+CMSPermSweepingEnabled,-XX:+CMSClassUnloadingEnabled
适用场景
- 短暂回收停顿时间,服务响应速度快的应用,尤其是互联网或基于B/S系统的服务上
缺点
- 抢占应用CPU
- GC耗时长
- 浮动垃圾
- 内存碎片
- Mintor GC耗时长,每次promotion提升都搜索free-list
组合
标准
吞吐量(throughput)=应用时间/总时间 关注耗时时间
暂停时间(Latency)关注每次GC造成的暂停
组合选择
- 单cpu或小内存,单机程序
-XX:+UseSerialGC
- 多cpu,需要大吞吐量,如计算型应用
-XX:+UseParallerGC或 -XX:+UseParallerOldGC
- 多cpu,追求停顿时间短,需要响应速度快的互联网应用
-XX:+UseConcMarkSweepGC -XX:ParNewGC
自动选择GC方式
- 吞吐量优先
-XX:GCTimeRatio=n
- 暂停时间短
-XX:MaxGCPauseMillis=n
- 一般不用
调优
堆大小的调优
- 堆越大越好
降低GC频率,单过大可能增加单次GC时间
对象更有可能成为垃圾
- 受硬件和系统的限制
32位操作系统单个进程最大可用内存2G,64无限
New和Old的比例
- 参数
-Xms=1024MB
-Xmx=1024MB
堆每次调整就会出发Full GC,避免调整可设置-Xms=-Xmx
新生代调优
- 增大Eden的大小
降低GC的频率
不一定会增大Mintor GC的时间
Mintor GC耗时与要拷贝的对象(存活对象多少成正比)
- 参数
-XX:NewSzie1024MB 新生代初始化大小
-XX:MaxNewSzie=1024MB 新生代最大大小
-XX:NewReatio=m New和Old比值
-Xmn=1024MB 新生代大小 (一般使用这个固定新生代大小)
新生代晋升
- 尽可能的让对象呆在Survivor中,是新生代收回
- 避免长时间存活对象在Survivor中不必要的拷贝
- 不容易找平衡点:better copy more ,than promote more
- -XX:SurvivorRatio=m Eden和Survivor比值
- 对象晋升年龄的阀值:Tenuring Threshold
旧生代调优
- 尽可能调优新生代
- 在不紧的的时间段手动Full GC
- 大小平衡
太大 GC时间长 太小 GC频率高
- 硬件优化
- 程序优化,避免无用对象在oldko空间
监控工具
- JVM参数
-XX:+PrintGC 输出GC简要信息
-XX:+PrintGCDetail 输出GC简要信息
-XX:+PrintGCTimeStamps 输出GC时间戳
-XX:+PrintGCApplicationStoppedTime 输出暂停时间
-Xlogg:c:/../xx.log 输出文件
- 命令行工具
查看内存使用情况,head dump:jmap+jhat
查看GC情况:jstat
JConsole:Java监视与管理控制台
JConsole(Java Monitoring and Management Console)是一种基于JMX的可视化监视、管理工
具。它管理部分的功能是针对JMX MBean进行管理,由于MBean可以使用代码、中间件服务器
的管理控制台或者所有符合JMX规范的软件进行访问。
VisualVM:多合一故障处理工具
VisualVM(All-in-One Java Troubleshooting Tool)是到目前为止随JDK发布的功能最强大
的运行监视和故障处理程序。VisualVM的还有一个很大的优点:不需要被监视的程序基于特殊
Agent运行,因此它对应用程序的实际性能的影响很小,使得它可以直接应用在生产环境
JMC,Oracle Java Mission Control 是一个用于对 Java 应用程序进行管理、监视、概要分析和
故障排除的工具套件。首次安装时,Java Mission Control 包括 JMX 控制台和 Java 飞行记录器。
从 Mission Control 中可以轻松安装更多插件
Eclipse EMemoryAnalyzer