背景:jvm实际调优在面试时候常常被问到,因此有必要认真总结一番。html
转自:JVM原理讲解和调优面试
4、JVM内存调优数组
首先须要注意的是在对JVM内存调优的时候不能只看操做系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用状况,由于GC事后这个值是不会变化的,所以内存调优的时候要更多地使用JDK提供的内存查看工具,好比JConsole和Java VisualVM。并发
对JVM内存的系统级的调优主要的目的是减小GC的频率和Full GC的次数,过多的GC和Full GC是会占用不少的系统资源(主要是CPU),影响系统的吞吐量。特别要关注Full GC,由于它会对整个堆进行整理,致使Full GC通常因为如下几种状况:jvm
旧生代空间不足
调优时尽可能让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要建立过大的对象及数组避免直接在旧生代建立对象 工具
Pemanet Generation空间不足
增大Perm Gen空间,避免太多静态对象 spa
统计获得的GC后晋升到旧生代的平均大小大于旧生代剩余空间
控制好新生代和旧生代的比例 操作系统
System.gc()被显示调用
垃圾回收不要手动触发,尽可能依靠JVM自身的机制 线程
调优手段主要是经过控制堆内存的各个部分的比例和GC策略来实现,下面来看看各部分比例不良设置会致使什么后果htm
1)新生代设置太小
一是新生代GC次数很是频繁,增大系统消耗;二是致使大对象直接进入旧生代,占据了旧生代剩余空间,诱发Full GC
2)新生代设置过大
一是新生代设置过大会致使旧生代太小(堆总量必定),从而诱发Full GC;二是新生代GC耗时大幅度增长
通常说来新生代占整个堆1/3比较合适
3)Survivor设置太小
致使对象从eden直接到达旧生代,下降了在新生代的存活时间
4)Survivor设置过大
致使eden太小,增长了GC频率
另外,经过-XX:MaxTenuringThreshold=n来控制新生代存活时间,尽可能让对象在新生代被回收
由内存管理和垃圾回收可知新生代和旧生代都有多种GC策略和组合搭配,选择这些策略对于咱们这些开发人员是个难题,JVM提供两种较为简单的GC策略的设置方式
1)吞吐量优先
JVM以吞吐量为指标,自行选择相应的GC策略及控制新生代与旧生代的大小比例,来达到吞吐量指标。这个值可由-XX:GCTimeRatio=n来设置
2)暂停时间优先
JVM以暂停时间为指标,自行选择相应的GC策略及控制新生代与旧生代的大小比例,尽可能保证每次GC形成的应用中止时间都在指定的数值范围内完成。这个值可由-XX:MaxGCPauseRatio=n来设置
最后汇总一下JVM常见配置
堆设置
-Xms:初始堆大小
-Xmx:最大堆大小
-XX:NewSize=n:设置年轻代大小
-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
-XX:MaxPermSize=n:设置持久代大小
收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
并发收集器设置
-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU状况。
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。