jvm参数:
-Xms:初始堆大小
-Xmx:最大堆大小
当最小堆占满后,会尝试进行GC,如果GC之后还不能失去足够的内存(GC未必会收集到所有以后可用内存),调配新的对象,那么就会扩大堆,如果-Xmx设置的太小,扩大堆就会失败,导致OutOfMemoryError谬误提醒。-Xms能够设置与-Xmx雷同,以防止每次垃圾回收实现后JVM从新分配内存。
-Xss:设置每个线程的堆栈大小。JDK5.0当前每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具利用的线程所需内存大小进行调整。在雷同物理内 存下,减小这个值能生成更多的线程。然而操作系统对一个过程内的线程数还是有限度的,不能有限生成,经验值在3000~5000左右。
-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数。并行收集线程数。
回收器抉择
JVM给了三种抉择:串行收集器、并行收集器、并发收集器,然而串行收集器只实用于小数据量的状况,所以这里的抉择次要针对并行收集器和并发收集器。默认状况下,JDK5.0以前都是应用串行收集器,如果想应用其余收集器须要在启动时退出相应参数。JDK5.0当前,JVM会依据以后系统配置进行判断。
调优总结
对JVM内存的零碎级的调优次要的目标是缩小GC的频率和Full GC的次数。
1.Full GC
会对整个堆进行整顿,包含Young、Tenured和Perm。Full GC因为须要对整个堆进行回收,所以比较慢,因而应该尽可能减少Full GC的次数。
2.导致Full GC的起因
1)年轻代(Tenured)被写满
调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创立过大的对象及数组防止间接在旧生代创建对象 。
2)长久代Pemanet Generation空间有余
增大Perm Gen空间,防止太多动态对象 , 管制好新生代和旧生代的比例
3)System.gc()被显示调用
垃圾回收不要手动触发,尽量依附JVM本身的机制
调优步骤
剖析内存透露、剖析Dump文件、监控GC状态、调整JVM参数
1.剖析内存透露
查看零碎产生cpu高和内存透露的过程,线程,找到具体产生问题的利用,定位到代码,通过优化代码来解决问题,比方,流没敞开,死循环,死锁等。
2.剖析dump文件
用jmap 生成dump文件,显然个别的Window零碎没有这么大的内存,必须借助高配置的Linux,几种工具关上该文件:
Visual VM
IBM HeapAnalyzer
JDK 自带的Hprof工具
Mat(Eclipse专门的动态内存剖析工具)举荐应用
备注:文件太大,倡议应用Eclipse专门的动态内存剖析工具Mat关上剖析。
通过剖析dump 内存快照文件,更加具体的全面的理解利用的jvm参数配置,gc过程,oom等。
3.监控GC的状态
应用各种JVM工具,查看以后日志,剖析以后JVM参数设置,并且剖析以后堆内存快照和gc日志,依据理论的各区域内存划分和GC执行工夫,感觉是否进行优化。
举一个例子: 零碎解体前的一些景象:
每次垃圾回收的工夫越来越长,由之前的10ms缩短到50ms左右,FullGC的工夫也有之前的0.5s缩短到4、5s
FullGC的次数越来越多,最频繁时隔不到1分钟就进行一次FullGC
年轻代的内存越来越大并且每次FullGC后年轻代没有内存被开释
之后零碎会无奈响应新的申请,逐步达到OutOfMemoryError的临界值,这个时候就须要剖析JVM内存快照dump。
剖析后果,判断是否须要优化
如果各项参数设置正当,零碎没有超时日志呈现,GC频率不高,GC耗时不高,那么没有必要进行GC优化,如果GC工夫超过1-3秒,或者频繁GC,则必须优化。
注:如果满足上面的指标,则个别不须要进行GC优化:
Minor GC执行工夫不到50ms;
Minor GC执行不频繁,约10秒一次;
Full GC执行工夫不到1s;
Full GC执行频率不算频繁,不低于10分钟1次;
4.调整参数
如果内存调配过大或过小,或者采纳的GC收集器比较慢,则应该优先调整这些参数,并且先找1台或几台机器进行beta,而后比拟优化过的机器和没有优化的机器的性能比照,并有针对性的做出最初抉择。
一直的剖析和调整
通过一直的试验和试错,剖析并找到最合适的参数,如果找到了最合适的参数,则将这些参数利用到所有服务器。
JVM调优参数参考
1.针对JVM堆的设置,个别能够通过-Xms -Xmx限定其最小、最大值,为了避免垃圾收集器在最小、最大之间膨胀堆而产生额定的工夫,通常把最大、最小设置为雷同的值;
2.年老代和年轻代将依据默认的比例(1:2)调配堆内存, 能够通过调整二者之间的比率NewRadio来调整二者之间的大小,也能够针对回收代。
比方年老代,通过 -XX:newSize -XX:MaxNewSize来设置其相对大小。同样,为了避免年老代的堆膨胀,咱们通常会把-XX:newSize -XX:MaxNewSize设置为同样大小。
3.年老代和年轻代设置多大才算正当
更大的年老代必然导致更小的年轻代,大的年老代会缩短一般GC的周期,但会减少每次GC的工夫;小的年轻代会导致更频繁的Full GC
更小的年老代必然导致更大年轻代,小的年老代会导致一般GC很频繁,但每次的GC工夫会更短;大的年轻代会缩小Full GC的频率
如何抉择应该依赖应用程序对象生命周期的散布状况: 如果利用存在大量的长期对象,比方高并发利用,应该抉择更大的年老代;如果存在绝对较多的长久对象,比方传输数量量大的利用,年轻代应该适当增大。但很多利用都没有这样显著的个性。
在抉择时应该依据以下两点:
(1)本着Full GC尽量少的准则,让年轻代尽量缓存罕用对象,JVM的默认比例1:2也是这个情理 。
(2)通过观察利用一段时间,看其余在峰值时年轻代会占多少内存,在不影响Full GC的前提下,依据理论状况加大年老代,比方能够把比例控制在1:1。但应该给年轻代至多预留1/3的增长空间。
4.在配置较好的机器上(比方多核、大内存),能够为年轻代抉择并行收集算法:-XX:+UseParallelOldGC**。
5.线程堆栈的设置:每个线程默认会开启1M的堆栈,用于寄存栈帧、调用参数、局部变量等,对大多数利用而言这个默认值太了,个别256K就足用。
实践上,在内存不变的状况下,缩小每个线程的堆栈,能够产生更多的线程,但这实际上还受限于操作系统,并不能无限大。