当前位置: 首页 > news >正文

【转】JVM 分代GC策略分析

我们以Sun HotSpot VM来进行分析,首先应该知道,如果我们没有指定任何GC策略的时候,JVM默认使用的GC策略。Java虚拟机是按照分代的方式来回收垃圾空间,我们应该知道,垃圾回收主要是针对堆(Heap)内存进行分代回收,将对内存可以分成新生代(Young Generation)、年老代(Tenured Generation)和永久代(Permanent Generation)三个部分。

分代GC

分代GC包括如下三代:

  • 新生代(Young Generation)

新生代有划分为Eden、From Survivor和To Survivor三个部分,他们对应的内存空间的大小比例为8:1:1,也就是,为对象分配内存的时候,首先使用Eden空间,经过GC后,没有被回收的会首先进入From Survivor区域,任何时候,都会保持一个Survivorq区域(From Survivor或To Survivor)完全空闲,也就是说新生代的内存利用率最大为90%。From Survivor和To Survivor两个区域会根据GC的实际情况,进行互换,将From Survivor区域中的对象全部复制到To Survivor区域中,或者反过来,将To Survivor区域中的对象全部复制到From Survivor区域中。

  • 年老代(Tenured Generation)

GC过程中,当某些对象经过多次GC都没有被回收,可能会进入到年老代。或者,当新生代没有足够的空间来为对象分配内存时,可能会直接在年老代进行分配。

  • 永久代(Permanent Generation)

永久代实际上对应着虚拟机运行时数据区的“方法区”,这里主要存放类信息、静态变量、常量等数据。一般情况下,永久代中对应的对象的GC效率非常低,因为这里的的大部分对象在运行都不要进行GC,它们会一直被利用,直到JVM退出。

 分代GC算法选择

  • 新生代

通常情况下会有大量的对象需要分配内存,而且他们的生命周期很短,所以新生代的GC吞吐量很高,大部分对象都要被回收,从而,剩下的活跃对象比较少,所以新生代适合使用复制算法来进行GC,这样保证复制的数据的量较小,效率最好。

  • 年老代

很多对象经过多次GC以后,经过Eden Space,多次经过From Survivor和To Survivor之后才会进入年老代,而且对象在年老代的存活时间比较长,如果进行使用复制算法来进行GC,需要移动大量的对象,导致效率很低。所以,年老代适合使用标记-清除算法(或者标记-清除-整理),需要被GC的对象很少,那么标记的对象就很少,在对标记的对象进行回收,效率就会很高。

默认GC策略

我们看一下,默认情况下,JVM针对上述不同的分代区域,使用哪些GC策略,如表所示:

运行模式新生代垃GC策略年老代GC策略
ClientSerial GCSerial Old GC
ServerParallel Scavenge  GCSerial Old GC(PS MarkSweep)

平时我们运行Java程序,没有指定任何选项的时候,默认根据上面的GC策略搭配进行GC。

GC策略搭配

在进行JVM调优的过程中,并非任何一种新生代GC策略都可以和另一种年老代GC策略进行配合工作,所以,我们应该知道,哪些种组合可以有效地进行GC,而且应该在什么样的应用场景下选择哪一种组合,如下表所示:

 新生代GC策略年老代GC策略说明
组合1SerialSerial Old
Serial和Serial Old都是单线程进行GC,特点就是GC时暂停所有应用线程。
组合2SerialCMS+Serial OldCMS(Concurrent Mark Sweep)是并发GC,实现GC线程和应用线程并发工作,不需要暂停所有应用线程。另外,当CMS进行GC失败时,会自动使用Serial Old策略进行GC。
组合3
ParNew
CMS
使用-XX:+UseParNewGC选项来开启。ParNew是Serial的并行版本,可以指定GC线程数,默认GC线程数为CPU的数量。可以使用-XX:ParallelGCThreads选项指定GC的线程数。
如果指定了选项-XX:+UseConcMarkSweepGC选项,则新生代默认使用ParNew GC策略。
组合4
ParNew
Serial Old使用-XX:+UseParNewGC选项来开启。新生代使用ParNew GC策略,年老代默认使用Serial Old GC策略。
组合5
Parallel Scavenge
Serial Old
Parallel Scavenge策略主要是关注一个可控的吞吐量:应用程序运行时间 / (应用程序运行时间 + GC时间),可见这会使得CPU的利用率尽可能的高,适用于后台持久运行的应用程序,而不适用于交互较多的应用程序。
组合6
Parallel Scavenge
Parallel Old
Parallel Old是Serial Old的并行版本

 

参考链接

  • http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
  • http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
  • http://blog.csdn.net/zhangren07/article/details/6270895

来源: http://shiyanjun.cn/archives/397.html


来自为知笔记(Wiz)


相关文章:

  • centos下编译安装MySQL5.7.16
  • Meta标签
  • OpenCV例程实现人脸检测
  • bt和wifi的共存
  • 使用Powershell链接到Office 365
  • Bootstrap-datepicker设置开始时间结束时间范围
  • django中的filter详解
  • CDN学习笔记二(技术详解)
  • macOS 中的 Rootless 机制
  • python环境搭建-设置PyCharm软件的配色方案和Python解释器
  • mod_fastcgi和mod_fcgid的区别
  • [摘录]第六章 用负激励促进新陈代谢
  • 4. 路由到控制器 - Laravel从零开始教程
  • 给MVC来一个谬论
  • linux 查看 cpu 和内存的命令 - top
  • [PHP内核探索]PHP中的哈希表
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  •  D - 粉碎叛乱F - 其他起义
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • mysql中InnoDB引擎中页的概念
  • ng6--错误信息小结(持续更新)
  • redis学习笔记(三):列表、集合、有序集合
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 猴子数据域名防封接口降低小说被封的风险
  • 回流、重绘及其优化
  • 移动端唤起键盘时取消position:fixed定位
  • 走向全栈之MongoDB的使用
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #1015 : KMP算法
  • #define用法
  • #每日一题合集#牛客JZ23-JZ33
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (31)对象的克隆
  • (AngularJS)Angular 控制器之间通信初探
  • (ZT)出版业改革:该死的死,该生的生
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET中winform传递参数至Url并获得返回值或文件
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • @AutoConfigurationPackage的使用
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [AIGC codze] Kafka 的 rebalance 机制
  • [CLickhouse] 学习小计
  • [HCTF 2018]WarmUp (代码审计)
  • [IDF]摩斯密码
  • [IE技巧] 使IE8以单进程的模式运行
  • [LeetCode]—Permutations 求全排列
  • [LeetCode]Spiral Matrix
  • [orleans2.1]这是你没玩过的船新版本
  • [PostgreSQL的 SPI_接口函数]
  • [shell,hive] 在shell脚本中将hiveSQL分离出去
  • [StartingPoint][Tier0]Synced