JVM内存系统的调优主要是为了减少GC的频率和Full GC的次数,过多的GC和Full GC会占用很多的系统资源(CPU),影响系统的吞吐量。触发这些操作的原因如下:
1、新生代设置过小
导致:(1)GC频繁操作,消耗系统资源;(2)会使得大对象直接进入老年代,占据老年代空间,触发Full GC
2、新生代设置过大
导致:(1)老年代过小,易触发Full GC;(2)新生代GC时间会变长
Note:一般来说新生代设置为堆的三分之一较为合理
3、Survivor(幸存区)设置过小
导致:对象从eden(伊甸)区直接到达老年区,降低了在新生代存活时间
4、Survivor设置过小
导致:eden区过小,增加了GC频率
Note:控制新生代存活时间,尽量让能够被回收的对象在新生代就被回收,通过-XX:MaxTenuringThreshold=n来控制
JVM提供的两条GC策略:
1、吞吐量优先
JVM以吞吐量为指标,自行选择相应的GC策略及控制新生代与旧生代的大小比例,来达到吞吐量指标。这个值可由-XX:GCTimeRatio=n来设置
2、暂停时间优先
JVM以暂停时间为指标,自行选择相应的GC策略及控制新生代与旧生代的大小比例,尽量保证每次GC造成的应用停止时间都在指定的数值范围内完成。这个值可由-XX:MaxGCPauseRatio=n来设置
*JVM调优:
查看堆空间大小分配(年轻代、年老代、持久代分配)
垃圾回收监控(长时间监控回收情况)
线程信息监控:系统线程数量
线程状态监控:各个线程都处在什么样的状态下
线程详细信息:查看线程内部运行情况,死锁检查
CPU热点:检查系统哪些方法占用了大量CPU时间
内存热点:检查哪些对象在系统中数量最大
*部分服务配置虚拟机参数:
-server --启用能够执行优化的编译器,显著提高服务器的性能
-Xmx4000M --堆最大值
-Xms4000M --堆初始大小
-Xmn600M --年轻代大小
-XX:PermSize=200M --持久代初始大小
-XX:MaxPermSize=200M --持久代最大值
-Xss256K --每个线程的栈大小
-XX:+DisableExplicitGC --关闭System.gc()
-XX:SurvivorRatio=1 --年轻代中Eden区与两个Survivor区的比值
-XX:+UseConcMarkSweepGC --使用CMS内存收集
-XX:+UseParNewGC --设置年轻代为并行收集
-XX:+CMSParallelRemarkEnabled --降低标记停顿
-XX:+UseCMSCompactAtFullCollection --在FULL GC的时候,对年老代进行压缩,可能会影响性能,但是可以消除碎片
-XX:CMSFullGCsBeforeCompaction=0 --此值设置运行多少次GC以后对内存空间进行压缩、整理
-XX:+CMSClassUnloadingEnabled --回收动态生成的代理类 SEE:http://stackoverflow.com/questions/3334911/what-does-jvm-flag-cmsclassunloadingenabled-actually-do
-XX:LargePageSizeInBytes=128M --内存页的大小不可设置过大, 会影响Perm的大小
-XX:+UseFastAccessorMethods --原始类型的快速优化 -XX:+UseCMSInitiatingOccupancyOnly --使用手动定义初始化定义开始CMS收集,禁止hostspot自行触发CMS GC -XX:CMSInitiatingOccupancyFraction=80 --使用cms作为垃圾回收,使用80%后开始CMS收集
-XX:SoftRefLRUPolicyMSPerMB=0 --每兆堆空闲空间中SoftReference的存活时间
-XX:+PrintGCDetails --输出GC日志详情信息
-XX:+PrintGCApplicationStoppedTime --输出垃圾回收期间程序暂停的时间
-Xloggc:$WEB_APP_HOME/.tomcat/logs/gc.log --把相关日志信息记录到文件以便分析.
-XX:+HeapDumpOnOutOfMemoryError --发生内存溢出时生成heapdump文件
-XX:HeapDumpPath=$WEB_APP_HOME/.tomcat/logs/heapdump.hprof --heapdump文件地址