优化Java堆大小的5个技巧
上一篇 / 下一篇 2012-07-27 09:23:08 / 个人分类:Java
本文作者Pierre是一名有10多年经验的高级系统架构师,他的主要专业领域是Java EE、中间件和JVM技术。根据他多年的工作实践经验,他发现许多性能问题都是由Java堆容量不足和调优引起的。下面他将和大家分享非常实用的5个Java堆优化技巧。51Testing软件测试网R?eH4e'Q2G
/F][y!{7XF0 1、JVM:对难以理解的东西产生恐惧感51Testing软件测试网M9aJ ?#a2X#I1T
KX|S(_.{9mww8}0 千万不要以为,通过配置,调优,就可以排除那些你所不明白的问题。有些人认为Java程序员不需要知道内部JVM内存管理。毫无疑问,这种观点明显是错误的,如果想拓宽知识面和提升排除故障能力,你就必须要了解和学习一下JVM内存管理。
spl0T.eAA6U/v0!k;i;@D+h7s"Vh0 对于Java或者是Java EE新手来说,Java Heap调优和故障排除是一项非常有挑战的工作。下面会提供一些典型的案例场景:51Testing软件测试网[2t5r,W+t#Wj
FM+? `&^6I;^0 客户端环境面临着有规律的OutOfMemoryError错误并且对业务造成了很大的影响。
9F P|e~ `%}5_onF0hr8wsyh%E;E0 你的开发团队要在如此大的压力下去解决这个问题,通常会怎么做?51Testing软件测试网#Xo1t5L@_!K |
51Testing软件测试网aq,sh&V1)用谷歌搜索引擎找到类似的问题并且你会相信(或假设)你也面临同样的问题。51Testing软件测试网 ] rBYU Z5L4h
q}"J~ ns~[0 2)你会抓住JVM-Xms和存在OutOfMemoryError异常这几个关键字的例子,然后希望通过这样的案例来快速解决客户端问题。51Testing软件测试网X'cn V ZkM2F
51Testing软件测试网@w!Qp]/[&Ma3)最后你会在你环境中使用相同的调优方法。两天后,问题仍然发生(甚至更糟或者稍微好点)……51Testing软件测试网`H {w:oi"w6j
VG#g4R)J$gsf0 到底是哪里错了呢?
*W2k5IN/g(dC3R0{(\9j4uFo Y4@ w#d;q{0 首先,没有摸清问题根源所在?对开发环境没有正确地进行深层面(规格、负载情况等)理解。网络搜索是一个非常优秀的学习方法和知识分享工具,但是你必须结合自己的实际项目,从根本上进行分析解决。51Testing软件测试网oO7wJW2I7ov w
51Testing软件测试网%Mw0dJP/HA*o可能缺乏基本的JVM和JVM内存管理技能,阻止你把所有的点给连接起来。51Testing软件测试网7BD$TVN1XS
51Testing软件测试网Q5h!~)Us9g今天讲的第一条技巧是帮助你理解基本的JVM原则及其与众不同的内存空间。这些知识都是相当重要的,它可以帮助你做出有效的调优策略、更加正确合理的预测将来会产生的影响、提前知道未来需要做哪些调优工作。下面来看一下JVM参考指南:
~x)\U2R%t.s'i051Testing软件测试网mS,s%w!?eJVM内存分为3个内存空间
!WWb;z4mB0f/U\#lc"X+~`!T\Lb0 ● Java Heap:适用于所有的JVM厂商,通常用来拆分YoungGen(幼苗)和OldGen(终身享用)空间。51Testing软件测试网*?(b4Rz!{4J
51Testing软件测试网#V(g MB3|l+tS● PermGen(永久代):适用于Sun HotSpot VM((PermGen空间在Java7或者Java8更新中将会被删除)51Testing软件测试网 h7\9H#f?O`
51Testing软件测试网 tZ&Wy.d9?● Native Heap(C-Heap):适用于所有的JVM厂商。51Testing软件测试网|(e&^YU Hr8A(l\
&c qE#SJ1C`v:iY0 正如你所看到的,JVM内存管理比使用Xmx设置最大值更为复杂。你需要查看每个角度,包括本地和PermGen需求以及从主机上查看物理内存可用性(CPU core)。51Testing软件测试网'Q6ecJ3_3A
51Testing软件测试网"hlAN#se;QT}@&i在较大的Java Heap和较小的本地Heap比赛中,32位虚拟机可能会变得相当棘手。试图在一个32位VM如2.5GB+上设置一个大型堆,根据应用程序占用和线程数 量等因素会增加OutOfMemoryError这个异常抛出。64位JVM可以解决这个问题,但物理资源可用性和垃圾回收成本仍然是有限制的(成本主要 集中在GC大小收集上)。最大并不表示是最好的,所以请不要假设在一个16GB的64位虚拟机上可以运行20个Java EE应用程序。
Z^"v8W(jH&q ] f051Testing软件测试网7n ~2JhQ C2、数据和应用程序为王:回顾静态占用需求
wi1_9b\!] Y.coe0})x:n6c P/\3K0 应用程序以及相关数据将决定Java堆空间占用需求。通过静态内存,可“预测”下面的内存需求:
1Pd|C4g U0}\-X3x$uwA3}0 ● 确定将会有多少不同的应用程序部署到预先计划的一个单独的JVM进程上,例如有多少个ear文件、war文件、jar文件等。在一个JVM上部署的应用程序越多,对本机堆的需求就越多。
b'[dk lx]051Testing软件测试网%X&yb-m-z● 确定有多少个类需要在运行时加载:包括第三方API。越多的类加载器和类在运行时被加载,在HotSpot VM PermGen空间和内部JIT相关优化对象上的需求就越高。51Testing软件测试网1y$MVu3xsJa8O3|
51Testing软件测试网(m H!N[B:Vh _/?:u3T● 确定数据缓存占用,如应用程序加载内部缓存数据结构(和第三方API),例如数据库中的数据缓存,从文件中读取数据等。数据缓存使用越多,Java Heap OldGen空间需求就越高。
4mm-G;bvh4oU_|051Testing软件测试网}hbn j● 确定允许建立的中间件线程数量。这是非常重要的,因为Java线程需要足够的本机内存,否则会抛OutOfMemoryError异常。51Testing软件测试网0KR9rZ8G Y#W7p
51Testing软件测试网Y c:w9q#o/Yp在JVM进程上部署的应用程序越多,对本地内存和PermGen空间的要求就越高。数据缓存并不是序列化为一个磁盘或数据库,它将从OldGen空间里面需要额外的内存。51Testing软件测试网 qj:k*Q5b M*[
51Testing软件测试网 k5xu,P\#x!r+@j s
设法对静态内存占用进行合理的评估,在真正进行数据测试之前,设置一些JVM能力起点是非常有用的。对于32位 JVM,通常不推荐一个Java堆大小超过2 GB(-Xms2048m,-Xmx2048m),对于Java EE应用程序和线程来说这样将需要足够的内存和本机堆PermGen。51Testing软件测试网c%TCTB
这个评估是非常重要因为太多的应用程序部署在一个32位JVM进程上很容易导致本机堆耗尽;尤其是在多重线程环境。51Testing软件测试网$OQ1M"P(_p_
对于64位JVM, 一个3GB或者4GB的Java堆/JVM进程是推荐的起点。51Testing软件测试网 AQC z C;bC[v
3、业务流量设置规则:审查动态内存占用需求51Testing软件测试网rkC2J5a)G
业务流量通常会决定动态内存占用。通过观察各种监控工具可以发现并发用户与请求生成的JVM GC“心跳”,这是由于频繁的创建和垃圾回收短期或者长期对象。51Testing软件测试网!O|4]"jLW2} [?
一个典型的32位JVM,Java堆大小设置在2 GB(使用分代&并发收集器)通常为500 MB YoungGen分配空间和1.5 GB的OldGen空间。
Rp"Y.h0S0最大限度地减少重大GC收集的频率是获得最佳性能的关键因素,所以在高峰的时候理解和评估需要多少内存是非常重要的。
-u c^ nR3N#ET0再次声明,应用程序类型和数据将决定内存需求。购物车的应用程序类型(长期居住的对象)涉及大型和非序列化会话数 据,这个通常需要大型Java堆和很多OldGen空间。无状态和XML处理(很多短命的对象)繁重的应用程序需要适当YoungGen空间,以尽量减少 频率主要集合。
G*i6DM&Y,A]0例如:51Testing软件测试网&u$y @,LH,KqUj {%{
你有5个ear应用程序(2000多个Java类)要部署(包含中间件代码)
$J|KR!a0l,O^01)本地堆需求估计为1GB(必须足够大以处理线程创建等等。)PermGen空间大约是512 MB。51Testing软件测试网4`(|/F'G\.\
2)内部静态缓存大约500MB
{\U.Mo03)在高峰时间,总预测流量是5000个并发用户
V ~isXwX;H04)每个用户的会话数据大约500K51Testing软件测试网i1hyr?
5)在高峰期间,总流量会话要求是2.5GB。
g s4VT L0 正如你所看到的一样,在如此情况下,32位JVM进程就无法满足。一个典型的解决方案是进行流量拆分,在几个JVM进程或物理主机(假设有足够的硬件和CPU core可用)上。51Testing软件测试网*Hx2B*ktAc/T5V0^大多数时候,业务流量将推动内存占用。除非你需要大量的数据缓存来实现适当的性能,典型的门户应用网站(媒体)繁重的应用程序需求。数据缓存太多的时候应该用一个黄色的标志标注一下,最好早点去重新审视一下一些设计元素。51Testing软件测试网R ~P8q&]'vWz-KJ
*?)vi^2DVy~(n0 4、量体裁衣
Fi3_yN0@G0fEFa9_+[$o9?+{0 这一条,你应该做到:
;\/qi6e:E#xT9c0f9cwFaJ}8YN0 1)理解基本的JVM原则和内存空间。
2y8i)Hi i6gq0.o3h6a*i&E