有许多现成的调优经验的介绍。Charlie Hunt写的《Java Performance》一书里有很详细的介绍。中文版就快出了,敬请关注。 
其中涉及GC调优的部分在过往的JavaOne里也有session介绍过。请搜这个标题:"Step-by-Step: Garbage Collection Tuning in the Java HotSpot™ Virtual Machine"

不过那种很具体的现成经验毕竟是别人在他们见过的环境里沉淀下来的,并不一定适用于所有情况。所以怎样的调优方法适合自己,还是得理解了系统底层的工作原理然后再在实际环境里加以应用、变通才好。

对HotSpot VM里的GC不熟悉的,至少应该把Sun以前出的HotSpot VM的GC调优白皮书读了。

====================

为啥HotSpot VM里收集有两种概念,一种是young GC/minor GC,另一种是full GC/major GC;为啥后者不是叫old GC?


因为young GC只收集young gen,但full GC会收集整个GC堆。 
HotSpot VM的full GC会收集整个Java堆,包括其中的young gen与old gen;同时也会顺便收集不属于Java堆的perm gen。 
Young + old + perm构成了HotSpot VM的整个GC堆。至少目前还是这样。 
(JDK8里的HotSpot VM就没有perm gen了。请注意。)

CMS在并发模式工作的时候是只收集old gen的。但一旦并发模式失败(发生concurrent mode failure)就有选择性的会进行全堆收集,也就是退回到full GC。

====================

大小分配怎样才合理取决于某个具体应用的对象的存活模式。

这涉及到分代式GC的原理。最初为何要把GC堆划分为多个区域,以不同的频率来收集它们?本来就是为了让每次收集的效率都最大(在收集的区域里尽可能回收出可用空间)。如果一个应用里对象的存活模式满足弱分代假设,那么把新生对象放在同一个区域里,每次收集这个区域的效率都应该比较高(因为假设是新生对象活不了多久就死了)。

有人专门研究这个。可以用"java object demography"这组关键字来搜已有资料。

====================

举例:可能很多人都有一种印象,young gen应该比old gen小。笼统说确实如此,因为在最坏情况下young gen里可能所有对象都还活着,而如果它们全部都要晋升到old gen的话,那old gen里的剩余空间必须能容纳下这些对象才行,这就需要old gen比young gen大(否则young GC就无法进行,而必须做full GC才能应付了)。 
实际上却不总是这样的。所谓“最坏情况”在很多系统里是永远不会出现的。调优就是要针对实际应用里对象的存活模式来破除这些“最坏情况”的假设带来的限制。

许多Web应用里对象会有这样的特征: 
·(a) 有一部分对象几乎一直活着。这些可能是常用数据的cache之类的 
·(b) 有一部分对象创建出来没多久之后就没用了。这些很可能会响应一个请求时创建出来的临时对象 
·(c) 最后可能还有一些中间的对象,创建出来之后不会马上就死,但也不会一直活着。

如果是这样的模式,那young gen可以设置得非常大,大到每次young GC的时候里面的多数对象(b)最好已经死了。 
想像一下,如果young gen太小,每次满了就触发一次young GC,那么young GC就会很频繁,或许很多临时对象(b)正好还在被是使用(还没死),这样的话young GC的收集效率就会比较低。要避免这样的情况,最好是就是把young gen设大一些。

那old gen怎么办?如果是上面说的情况,那old gen至少要足以装下所有长期存活的对象(a);同时也要留出一定的余地用来容纳young GC没能清理掉的临时对象。

这样,最后调整出来的结果很可能young GC反而比old gen大许多。这完全没问题。

只有(a)和(b)的话就完美了,现实中最头疼的就是针对(c)对象的调优。它们或许会经历多次young GC之后仍然存活,于是晋升到old gen;但晋升上去之后或许很快就又死掉了。 
这种对象最好能不让晋升到old gen(可以让它们在survivor space里多来回倒腾几次再晋升,也就是想办法增加tenuring threshold;不过HotSpot VM里的GC不让外界对此多插手,想减小MaxTenuringThreshold很容易,想增加实际有效的tenuring threshold就没那么容易了)。但如果真的不让它们晋升,young GC的暂停时间就会增长(在survivor space里来回倒腾对象意味着要来回拷贝,这会花时间)。 
所以有一种策略是尽量让这种对象的大部分在young GC中消耗掉(在保持young GC的暂停时间不超过某个预期值的前提下),而“漏”到old gen的那些让诸如CMS之类的并发GC来解决。 
总之这里要做一定的tradeoff就是了。

=================

知道了原理之后在现实中要如何实践呢?

首先得了解硬性限制:某个服务器总共有多少内存,其中最多可以分配多少给某个应用程序;有没有一些服务对响应时间有严格要求,有的话限制是多少,之类的。

然后看看应用的特征是怎样的。可以借助一些工具来了解对象的存活情况,例如NetBeans的profiler就有这样的功能(老文档);许多其它主流Java profiler也有类似的功能。 
这些工具的精度和性能开销各异,总之自己摸索下看看吧。

情况了解清楚了就可以开始迭代调整各种参数看实际运行的表现如何。迭代到满意为止。 
要分析实际GC的运行状况,首要切入点就是分析GC日志。有很多工具能把HotSpot VM的GC日志可视化。我以前一直在用的是这个:GCHisto。 
然后像Twitter做的这个工具也可以抽取一些GC的辅助统计信息:https://github.com/twitter/jvmgcprof

=================

那个…上面随便写了些。文字不通顺的地方请轻拍,要整理成“文章”的话又要烧脑细胞了…

没说清楚的地方请另外补充背景知识… 
例如这个:http://www.infoq.com/interviews/szegedi-performance-tuning,Attila Szegedi的GC调优经验。 
还有这个:http://www.infoq.com/presentations/Understanding-Java-Garbage-Collection,Gil Tene谈GC。

   
如果老年代设置过小,就会频繁触发full gc,full gc是非常耗时的。年轻代在经过n(hotspot默认是15)轮后会进入老年代,这样老年代顶不住了,就会触发full gc,回收时需要stop the world,这样系统经常发生长时间停顿,影响系统的吞吐量

原文地址:http://blog.sina.com.cn/s/blog_4adc4b090102vr1v.html

JVM 年轻代和年老代 大小设置相关推荐

  1. JVM分化回收机制(年轻代、年老代、永久代)

    分代回收机制:JVM将堆内存划分为Eden.Survivor和Tenured/Old空间. (Minor GC )年轻代 :Eden.Survivor.尽可能快的收集生命周期短的对象. 在年轻代中经历 ...

  2. java年轻代和年老代默认比值_JAVA中的GC以及年轻代,年老代,持久代的认识

    java中我们常常谈论到垃圾回收机制,那么,垃圾回收机制又是什么呢?说到JVM调优,似乎很高大上,那么JVM调的都是那些数据呢?伊甸园区,幸存区,年轻代,年老代,持久代,每个词都熟悉又陌生,似乎很深奥 ...

  3. Jave虚拟机划分的三个代: 年轻代、年老代和持久代

    转载自:点击打开链接 虚拟机中的共划分为三个代: 年轻代(Young Generation).年老代(Old Generation)和持久代(Permanent  Generation).其中持久代主 ...

  4. 年轻代、年老代和持久代

    年轻代(Young Generation).年老代(Old Generation)和持久代(Permanent  Generation).其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的J ...

  5. Java 年轻代、年老代、GC

    一篇关于gc的文章 http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html 自己的笔记: JVM是用c语言写的.一般说的JVM是 ...

  6. 是堆内存分为年轻代和年老代!!!

    1.是堆内存分为年轻代和年老代!!! 2.是堆内存分为年轻代和年老代!!! 3.是堆内存分为年轻代和年老代!!! 4. 1) 在Young Generation中,有一个叫Eden Space的空间, ...

  7. 内存管理_分代机制(年轻代、年老代、永久代)

    通用的分代垃圾回收机制 分代垃圾回收机制,是基于这样一个事实,不同的对象的生命周期是不一样的.因此,不同的生命周期的对象可以采用不同的回收算法,便以提高回收效率,我们将对象分为三种状态:年轻代.年老代 ...

  8. 年轻代和年老代分配过大 或 过小

    我们都知道 堆内存被分为年轻代 和 年老代 ,默认比例是1:2. 年轻代占1/3. 年轻代 gc使用的算法是 copy算法(速度快,但是会浪费一个survivor内存),年老代使用的是 标记整理算法( ...

  9. jvm 年轻代、年老代、永久代

    关键字约定 Young generation –>新生代 Tenured / Old Generation –>老年代 Perm Area –>永久代 年轻代: 所有新生成的对象首先 ...

  10. JVM的年轻代、年老代(老年代)和永生代(持久代)【Loadrunner性能调优】

    1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...

最新文章

  1. 软件调试修炼之道之——反思
  2. Cassandra 数据模型设计,根据你的查询来制定设计——反范式设计本质:空间换时间...
  3. 【分享】怎样学习一门新技术?
  4. 使用Spring 3引导Web应用程序
  5. Javascript模拟c#中arraylist操作(学习分享)
  6. Raid技术精简总结
  7. [POI2004]GRA
  8. 程序员的代码为什么永远写不完?
  9. 详述 ISC BIND 服务器中的信息泄露漏洞
  10. Android 实现 相机、相册功能 + 图片存取数据库操作
  11. j2me解决模拟器乱码
  12. cocos creator性能优化合集
  13. AVR单片机开发11——1602液晶屏幕
  14. leetcode笔记(五)809. Expressive Words
  15. 使用js脚本实现网页版微信定时发送信息
  16. 对话论答创始人王枫:“TAD”战法布局AI教育 让每个孩子都能享受优质教育
  17. 狄拉克函数- dirac 分布
  18. 软件测试面试前必备题库(必备理论基础复习)
  19. android 发短信 oppo,oppo手机怎么自动回复短信?oppo手机自动回复信息设置教程
  20. 报表导出HTML格式怎么转换为EXCEL,使用html导出excel时的格式问题

热门文章

  1. 求树的直径的两种方法
  2. c语言规定 标识符由,【填空题】C语言的标识符命名规则规定标识符可以由字母数字和下划线组成,首字符不能是 。 (4.0分)...
  3. [转]sed命令详解
  4. 技术分享 | 无人机仿真教程-Prometheus平台 -转自阿木实验室
  5. 单目标优化算法测试函数python绘制及相关代码
  6. C语言中的字符串与字符串函数
  7. vue3源码系列之计算属性computed原理剖析
  8. Gerrit的安装和配置个人经验总结
  9. 2.H.265/HEVC —— 帧内预测
  10. Excel VBA初级系列培训--课时1