1.方法
1.1 假设条件
1.2 测试基础设施需求
2.应用程序的系统需求
2.1 可用性
可用性是对应用程序处于可操作、可使用状态的度量。可用性需求指的是当应用程序的某些组件发生故障或失效时,应用程序或应用程序的一部分在多大程度上还可以继续提供服务。
2.2 可管理性
可管理性是对由运行、监控应用程序而产生的操作性开销的度量,同时也包含了配置应用程
序的难易程度。
2.3 吞吐量
吞吐量是对单位时间内处理工作量的度量。设计吞吐量需求时,我们一般不考虑它对延迟或者响应时间的影响。通常情况下,增加吞吐量的代价是延迟的增加或内存使用的增加。
2.4 延迟及吞吐量
延迟,或者响应性,是对应用程序收到指令开始工作直到完成该工作所消耗时间的度量。
2.5 内存占用
内存占用指在同等程度的吞吐量、延迟、可用性和可管理性前提下,运行应用程序所需的内存大小。
2.6 启动时间
启动时间是应用程序初始化所消耗的时间。
3.对系统需求的分级
调优过程的第一步是划分应用程序的系统需求优先级,我们需要在一开始就与应用程序的重要干系人一起讨论,并就其优先级达成一致。由于这项工作明确定义了哪些是应用程序最重要的需求,所以应该作为应用程序架构设计的一部分。
4.选择jvm部署模式
4.1 单jvm部署模式
4.2 多个jvm部署模式
4.3 通用建议
5.选择jvm运行模式
5.1 Client模式或Server模式
HotSpot VM时有2种JVM运行模式可以选择, 分别是:Client模式或Server模式。
Client模式的特点是启动快、占用内存少、JIT编译器生成代码的速度也更快。Server模式则提供了更复杂的生成码优化功能, 这个功能对于服务器应用而言尤其重要。
大多数Server模式的JIT编译优化都要消耗额外的时间以收集更多的应用程序行为信息、为应用程序运行生成更优的生成码
5.2 32位/64位 jvm
5.3 垃圾收集器
垃圾收集器:Serial收集器、Throughput收集器、Mostly-Concurrent收集器及G 1收集器(也称
Garbage First收集器) 。
-XX:+UseParallelOldGC
是-XX:+UseParallelOldGC将同时启用多线程的新生代垃圾收集器和多线程的老年代垃圾收集器, 即Minor GC和Full GC都采用多线程
-XX:+UseParallelGC
-XX:+UseParallelGC仅启用了多线程的新生代垃圾收集器。使用-XX:+UseParallelGC选项的老年代垃圾收集器仍采用单线程。
6 垃圾收集调优基础
6.1 性能属性
吞吐量:是评价垃圾收集器能力的重要指标之一,指不考虑垃圾收集引起的停顿时间或内存消耗,垃圾收集器能支撑应用程序达到的最高性能指标。
延迟:也是评价垃圾收集器能力的重要指标,度量标准是缩短由于垃圾收集引起的停顿时间或完全消除因垃圾收集所引起的停顿,避免应用程序运行时发生抖动。
内存占用:垃圾收集器流畅运行所需要的内存数量。
6.2 原则
每次Minor GC都尽可能多地收集垃圾对象。我们把这称作“Minor GC回收原则”。遵守这一原则可以减少应用程序发生Full GC的频率。Full GC的持续时间总是最长的, 是应用程序无法达到其延迟或吞吐量要求的罪魁祸首。
处理吞吐量和延迟问题时, 垃圾处理器能使用的内存越大, 即Java堆空间越大, 垃圾收集的效果越好,应用程序运行也越流畅。我们称之为“GC内存最大化原则”。
在这三个性能属性(吞吐量、延迟、内存占用) 中任意选择两个进行JVM垃圾收集器调优。我们称之为“GC调优的3选2原则”
6.3 命令行选项及GC日志
-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -X1oggc:
-XX:+PrintGCTimeStamps打印从HotSpot VM启动直到GC开始所经历的时间(以秒计时) 。
-XX:+Print GCDetails提供垃圾收集器相关的统计数据, 该选项的输出与使用的垃圾收集器密切相关,所以使用不同的垃圾收集器输出结果会有不同。
-X1oggc:
45.152:[GC
[PSYoungGen:295648K->32968K(306432K)]
296198K->33518K(1006848K) , 0.1083183secs]
[Times:user=1.83sys=0.01, re a 1=0.11secs]
45.152是从JVM启动直到垃圾收集发生所经历的时间。GC标签表明这是一次Minor GC, 或者称之为新生代垃圾收集。
[PSYoungGen:295648K->32968K(306432K) ] 提供了新生代空间的信息。PSYoung Gen表示新生代使用的是多线程垃圾收集器Parallel Scavenge。
箭头(->)左边的295648K代表的是垃圾收集之前新生代占用的空间。
箭头右边代表的是垃圾收集之后新生代占用的空间。
新生代空间又进一步细分成了一个Eden空间和两个Survivor空间。
Minor GC之后Eden空间为空, 所以箭头右边的32968K就是Survivor占用的空间。
296198K->33518K(1006848K)
箭头左边的296198K是垃圾收集之前Java堆占用的大小。
箭头右边的33518K是垃圾收集之后Java堆占用的大小。
括号内的数值(1006848K) 代表的是Java堆的总大小。
由新生代和Java堆占用的大小, 你可以很快推算出老年代占用的空间。例如,
Java堆的大小是1006848K,新生代堆占用的空间是306432K,
那么老年代堆占用的空间就是1006848K-306432K=700416K。
垃圾收集之前,老年代占用的空间是296198K-295648K=550K。
垃圾收集之后,老年代占用的空间是33518K-32968K=550K。
0.1083183secs表示垃圾收集过程所耗的时长。
[Times:user=1.83sys=0.01, re a 1=0.11secs] 提供了CPU使用及时间消耗的情况。
user是用户模式垃圾收集消耗的CPU时间,即运行于JVM中的时间..本例中,垃圾收集消耗了1.83秒的用户态CPU时间。
sys是垃圾收集器消耗的系统态CPU时间。本例中, 垃圾收集器消耗了0.01秒系统态CPU时间。
real指垃圾收集消耗的实际时间(以秒计数) 。本例中, 垃圾收集消耗了0.11秒。
用户态(user) 、系统态(sys) 及实际消耗(real) 都四舍五入并精确到0.01秒。
-XX:PrintGCDateStamps: -XX:+PrintGCDetails:
2010-11-21T09:57:10.518-0500:[GC
[PSYoungGen:295648K->32968K(306432K)]
296198K->33518K(1006848K) , 0.1083183secs]
[Times:user=1.83sys=0.01, re a 1=0.11secs]
GC命令行选项 | 使用场景 |
---|---|
-XX:+PrintGCTimeStamps | 适用于所有应用程序的最小命令行选项集 |
-XX:+PrintGCDetails -X1oggc: -XX:Print GC Date Stamps |
当需要显示日历日期和时间而非从JVM启动开始经历的秒数时, 可以使用该选项。该选项从Java6 Update 4之后开始支持 |
-XX:+Print GCApplicationStoppedTime -XX:+Print GCApplicationConcurrentTime -XX:+PrintSafepointStatistics |
用于调优响应时间/延迟较高的应用程序,可以帮助区分是VM的安 全点操作还是其他源头导致的停顿事件 |
7.确定内存占用
活跃数据的大小是指, 应用程序稳定运行时长期存活对象所占用的Java堆内存量。换句话说,它是应用程序运行于稳定态时, Full GC之后Java堆所占用的空间大小。
7.1 约束
7.2 HotSpot VM堆的布局
-Xmx, -Xms命令行选项指定了新生代和老年代空间大小的初始值和最大值
-Xms设定了初始及最小值.
-Xmx可以设定最大值。
-XX:NewSize=
-XX:MaxNewSize=
-Xmn
只有在-Xms与-Xmx设定为同一值时才使用-Xmn选项
-XX:PermSize=
-XX:MaxPermSize=
如果FullGC缘于老年代空间已满,即使永久代空间并没有用尽, 老年代和永久代都会进行垃圾收集。同样,如果Full GC由永久代空间用尽引起,老年代和永久代也都会进行垃圾收集,无论老年代是否还有空闲空间。开启-XX:+UseParallelGC或-XX:+UseParalleloldGC时, 如果关闭-Xx:-Scavenge Before Fu11GC, HotSpot VM在FullGC之前不会进行Minor GC, 但Full GC过程中依然会收集新生代; 如果开启-XX:+Scavenge Before Fu11GC, HotSpot VM在Full GC前会先做一次Minor GC, 分担一部分Full GC原本要做的工作。
7.3 堆大小调优着眼点