1. 堆栈大小设置
JVM内存大小=年轻代大小(包括Eden和两个Survivor区) + 年老代大小 + 持久代大小
-Xmx JVM最大可用内存
-Xms初始内存 JVM优化
-Xmn年轻代大小
-Xss每个线程的堆栈大小
-XX:NewRatio 年轻与年老的比值
-XX:SurvivorRatio 一个Survivor与eden的比值,如果=4 一个Survivor占年轻代的1/6
-XX:MaxPermSize设置持久代大小
堆与栈
栈是运行时的单位,而堆是存储的单位。
2. Young回收器选择:
Serial:串行
Parrel New:多线程,类似于串行
Parrel Scavenge:吞吐量优先,通过GCTimeRatio设置gc占用cpu比例(19:1/(1+19))
UseAdaptiveSizePolicy不适于ParrelNew,仅在UseParrelGC/UseParrelOldGC使用
3. old回收器选择
Serial Old:
CMS:
Parrel Old:
当虚拟机参数为UseParrelGC:Parrel Scavenge+Serial Old
当虚拟机参数为UseParrelOldGC:Parrel Scavenge+Parrel Old
当虚拟机参数为UseConcMarkSweepGC:Parrel New+CMS
4. 辅助信息
-XX:+PrintGC
输出形式:[GC 118250K->113543K(130112K), 0.0094143 secs]
[Full GC 121376K->10414K(130112K), 0.0650971 secs]
-XX:+PrintGCDetails
输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]
[GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
DefNew: 8614K->781K(9088K):新生代回收情况(Eden+1Survivor)
118250K->113543K(130112K):整个Heap(Eden+1Survivor+Old) 回收情况及大小
DefNew:是使用-XX:+UseSerialGC(新生代,老年代都使用串行回收收集器)。
ParNew:是使用-XX:+UseParNewGC(新生代使用并行收集器,老年代使用串行回收收集器)或者-XX:+UseConcMarkSweepGC(新生代使用并行收集器,老年代使用CMS)。
PSYoungGen:是使用-XX:+UseParallelOldGC(新生代,老年代都使用并行回收收集器)或者-XX:+UseParallelGC(新生代使用并行回收收集器,老年代使用串行收集器)
garbage-first heap:是使用-XX:+UseG1GC(G1收集器)
-XX:+PrintGCTimeStamps(GC发生的时间)
-XX:+PrintGCApplicationStoppedTime(GC消耗了多少时间)
-XX:+PrintGCApplicationConcurrentTime(GC之间运行了多少时间)
-Xloggc:filename:与上面几个配合使用,把相关日志信息记录到文件以便分析。
PrintHeapAtGC会打印Heap信息
5. 总结
1. MTT与TargetSurvivorRatio
查看jstat -gcnew 会有两列信息 TT MTT
TT:tenure threshold,经过minor gc次数 仍然没有被回收 则晋升到old
MTT:max tt,tt会根据age自动计算,下一次min gc的tt,是age与mtt的最小值
age:每个对象有4bit用于存储 min gc后的存活次数,min gc发生后会统计各个age阶段所占suvivor的比率,如果某个age的对象大小之和大于TargetSurvivorRatio(有个计算公式,这个参数是比率),而且还没到mtt,则tt设置为age
TargetSurvivorRatio默认50%,所以调大 有利于对象在young回收,但是设置过大,长期存在的对象会反复被拷贝,所以需要一个权衡。
加入-XX:+PrintTenuringDistribution可以查看minor gc时 各个age的对象大小
2. 年老代大小选择
响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:
并发垃圾收集信息
持久代并发收集次数
传统GC信息
3.花在年轻代和年老代回收上的时间比例
减少年轻代和年老代花费的时间,一般会提高应用的效率
吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。
参考文档:
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
http://www.iteye.com/topic/91905
http://www.iteye.com/topic/473874
http://www.tikalk.com/java/garbage-collection-serial-vs-parallel-vs-concurrent-mark-sweep
http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html