当前位置: 首页 > 后端技术 > Java

JVM参数调整

时间:2023-04-01 17:42:42 Java

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区在新生代中的比例。请注意,有两个幸存者区域。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5XX:+UseParallelGC:SetParallelCollector-XX:+UseParalledlOldGC:SetParallelOldGenerationCollector-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的频率和FullGC的次数。1.FullGC会组织整个堆,包括Young、Tenured和Perm。FullGC比较慢,因为需要回收整个堆,所以FullGC的次数要尽量减少。2、FullGC的原因1)老年代(Tenured)满调优时,尽量让对象在新生代GC中被回收,让对象在新生代中存活更长时间,做不要创建太大的对象和数组避免直接在老年代创建对象。2)PermGenerationPemanetGeneration空间不足增加PermGen空间,避免静态对象过多,控制新生代和老年代的比例3)显示System.gc()调用垃圾回收,不触发手动,尽量依靠JVM本身机制调优步骤分析内存泄漏,分析Dump文件,监控GC状态,调整JVM参数1.分析内存泄漏检查系统中cpu和内存泄漏高的进程和线程,查找具体有问题的应用程序,定位到代码,通过优化代码来解决问题,比如unclosedstream、死循环、死锁等。2.分析dump文件,使用jmap生成dump文件。显然,一般的Window系统是没有这么大内存的。必须使用高配置的Linux和几个工具才能打开文件:VisualVMIBMHeapAnalyzerJDK自带的Hprof工具Mat(Eclipse专用静态内存分析工具)推荐使用备注:文件太大,建议使用Eclipse专用静态内存分析工具Mat打开分析。通过分析dumpmemorysnapshot文件,可以更详细、全面的了解应用的jvm参数配置、gc进程、oom等。3.监控GC状态使用各种JVM工具查看当前日志,分析当前JVM参数设置,分析当前堆内存快照和gc日志。可以根据每个区域实际的内存划分和GC执行时间来决定是否优化。举个例子:系统崩溃前的一些现象:每次垃圾回收的时间越来越长,从之前的10ms到50ms左右,FullGC的时间也从之前的0.5s延长到4s,并且5sFullGC的次数在增加,最频繁的FullGC每不到1分钟执行一次。老一代的内存越来越大。每次FullGC后,老年代的内存都没有释放,系统将无法响应新的请求,逐渐达到OutOfMemoryError的临界值。这时候就需要分析JVM内存快照转储了。分析结果以确定是否需要优化。如果参数设置合理,系统没有超时日志,GC频率不高,GC耗时不高,那么就没有必要进行GC优化。如果GC时间超过1-3秒,或者GC频繁,则必须进行优化。注意:如果满足以下指标,一般不需要GC优化:MinorGC执行时间小于50ms;MinorGC执行频率不高,大约每10秒一次;FullGC执行时间小于1s;FullGC执行频率不频繁,不少于10分钟一次;4.调整参数如果内存分配太大或太小,或者使用的GC收集器比较慢,你应该先调整这些参数,先找一台或几台机器进行测试,然后比较优化后的机器和性能未优化的机器,并做出有针对性的最终选择。不断的分析和调优通过不断的试错,分析并找到最合适的参数,如果找到,则将这些参数应用于所有服务器。JVM调优参数参考1.对于JVM堆设置,一般可以通过-Xms-Xmx来限制它的最小值和最大值。最小设置是相同的值;2、新生代和老年代会按照默认的比例(1:2)分配堆内存。可以通过调整NewRadio的比例来调整两者之间的大小,也可以用于回收。例如,新生代的绝对大小由-XX:newSize-XX:MaxNewSize设置。同样,为了防止新生代堆收缩,我们通常将-XX:newSize-XX:MaxNewSize设置为相同的大小。3.合理设置新生代和老年代的大小。更大的年轻一代将不可避免地导致更小的老年代。大新生代会延长普通GC的周期,但会增加每次GC的时间;老年代会导致更频繁的FullGC。较小的新生代必然导致较大的老年代。年轻代小会导致频繁的普通GC,但每次GC时间会更短;大老年代会减少FullGC频率的选择应该取决于应用对象生命周期的分布:如果应用有大量的临时对象,比如高并发应用,应该选择更大的年轻代选中;如果持久化对象比较多,比如传输次数比较大的应用,应该适当增加老年代。但是许多应用程序没有这样明显的功能。选择应该基于以下两点:(1)基于FullGC越少越好的原则,尽可能让老年代缓存普通对象。JVM默认的比例是1:2,也是这个原因。(2)观察应用一段时间,看看老年代在高峰期会占用多少内存。在不影响FullGC的情况下,根据实际情况增加年轻代的大小。例如,比例可以控制在1:1。但至少要为老年代保留1/3的增长空间。4、在配置较好的机器上(如多核、大内存),可以选择老年代的并行收集算法:-XX:+UseParallelOldGC**。5、线程栈设置:每个线程默认会开一个1M的栈,用来存放栈帧、调用参数、局部变量等,这个默认值对于大多数应用来说太大了,一般256K就够了。理论上,在内存相同的情况下,减少每个线程的栈可以产生更多的线程,但这实际上受限于操作系统,不可能是无限的。