-Xms:初始堆大小 -Xms:最大堆大小 -XX:NewSize=n:设置年轻代大小 -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3表示年轻代和年老代比值为1:3,年轻代占整个年轻代年老代和的1/4 -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如3表示Eden: 3 Survivor:2,一个Survivor区占整个年轻代的1/5 -XX:MaxPermSize=n:设置持久代大小
说明:
一、通常初始堆和最大堆设置同样,由于:如今内存不是什么稀缺的资源,可是若是不同,从初始堆到最大堆的过程会有必定的性能开销,因此通常设置为初始堆和最大堆同样。64位系统理论上能够设置为无限大,可是通常设置为4G,由于若是再大,JVM进行垃圾回收出现的暂停时间会比较长,这样全GC过长,影响JVM对外提供服务,因此不能太大。通常设置为4G。
二、-XX:NewRaio和-XX:SurvivorRatio这两个参数,都是设置年轻代和年老代的大小的,设置一个便可,第一是设置年轻代的大小,第二个是设置比值,理论上设置一个既能够知足需求java
-XX:+UseSerialGC:设置串行收集器 -XX:+UseParallelGC:设置并行收集器 -XX:+UseParalledlOldGC:设置并行年老代收集器 -XX:+UseConcMarkSweepGC:设置并发收集器
打印GC回收的过程日志信息算法
-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中最大堆大小有三方面限制:相关操做系统的数据模型(32bit仍是64bit)限制:系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,通常限制在1.5G-2G;64位操做系统对内存没有限制。在Windows Server 2003系统,3.5G物理内存,JDK5.0下测试,最大设置为1478m。并发
典型设置:eclipse
java-Xmx3550m -Xms3550m-Xmn2g -Xss128k -Xmx3550m:设置JVM最大可用内存为3550m -Xms3550m:设置JVM初始内存为3550m,此值能够设置-Xmx相同,以免每次垃圾回收完成之后JVM从新分配内存 -Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。持久代通常固定为64M,因此增大年轻代后,将会减小年老代大小,此值对系统性能影响比较大,Sun官方推荐配置为整个堆的3/8 -Xss128k:设置每一个线程的堆栈大小。JDK5.0之后每一个线程栈大小为1M,之前每一个线程堆栈大小为256k。根据应用的线程所须要内存大小进行调整。在相同物理内存下,减小这个值可以生成更多的线程。可是操做系统对一个进程内的线程仍是有限制的,不能无限生成,经验值在3000-5000左右。
java -Xmx3550m-Xms3550m-Xss128k-XX:NewRatio=4-XX:SurvivorRatio=4 -XX:MaxPermSize=16m-XX:MaxTenuringThreshold=0 -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代和年老代所占比值为1:4,年轻代占整个堆栈的1/5 -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6 -XX:MaxPermSize=16m:设置持久代大小为16m -XX:MaxTenuringThreshold=0:设置垃圾最大年龄。若是设置为0,则年轻代对象不通过Survivor区,直接进入年老代。对于年老代比较多的应用,提升效率,若是将此值设置为一个较大值,则年轻代对象会在Survivor区进行屡次复制,这样能够增长对象在年轻代的存活时间。
JVM给了三种选择:串行收集器,并行收集器,并发收集器,可是串行收集器只适用于小数据量的状况,通常不考虑使用了,因此这里只针对并行收集器和并发收集器。默认状况下,JDK5.0之前是使用的串行收集器,若是想使用其余收集器须要在启动时加入相应的参数,JDK5.0之后,JVM会根据系统当前的配置进行判断工具
吞吐量优先的并行收集器
并行收集器主要以到达必定的吞吐量为目标,适用于后台处理性能
java -Xmx3550m-Xms3550m-Xss128k-XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelGC:选择垃圾收集器为并行收集器。次配置仅对年轻代有效。即上述配置下,年轻代使用并行收集,而年老代仍旧使用串行收集。 -XX:PARALLELgcThreads=20:配置并行收集器的线程数,即:同时多少个线程一块儿进行垃圾回收。此值最好配置与处理器数目相同。 -XX:+UseParallelOldGC:配置年老代来及收集方式为并行收集,JDK6.0支持对年老代并行收集 -XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,若是没法知足此时间,JVM会自动调全年轻代大小,以知足此值 -XX:+UseAdaptiveSizePolicy:设置此选项之后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低响应时间或者收集频率等,此值建议使用并行收集器时,一直打开
响应时间优先的并发收集器
并发收集器主要是保证系统的响应时间,减小垃圾收集时的停顿时间。适用于应用服务器、电信领域等。测试
-XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction:因为并发收集器不对内存空间进行压缩、整理、因此运行一段时间之后会产生“碎片”,使得运行效率下降。此值设置运行多少次GC之后对内存空间进行压缩、整理 -XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,可是能够消除碎片
年轻代大小选择
响应时间优先的应用:尽量设置大,直到接近系统的最低响应时间限制(根据实际状况选择)。在此种状况下,年轻代收集发生的频率也是最小的。同时减小到达年老代的对象。
吞吐量优先的应用:尽量的设置大,可能到达Gbit的成都,由于对响应时间没有要求,垃圾收集能够并行进行,通常适合8核CPU以上应用。优化
年老代大小选择
响应时间优先的应用:年老代使用并发收集器,因此其大小须要当心设置,通常要考虑并发会话率和会话持续时间等一些参数。若是堆设置小了,可能会形成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;若是堆大了,则须要较长的收集时间。最优化的方案,通常须要参考一下数据得到:
一、并发垃圾收集信息
二、持久代并发收集次数
三、传统GC信息
四、花在年轻代和年老代回收上的时间比例减小年轻代和年老代花费的时间,通常会提升应用的效率spa
吞吐量优先的应用
通常吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。缘由是,这样能够尽量回收掉大部分短时间对象,减小中期对象,而年老代尽存放长期存活的对象
较小堆引发的碎片问题
由于年老代的并发收集器使用标记、清除算法,因此不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样能够分配给较大的对象。可是当堆空间较小时,运行一段时间之后,就会出现“碎片”,若是并发收集器找不到足够的空间,那么并发收集器将会中止,而后使用传统的标记、清除方式进行回收。若是出现“碎片”,可能须要进行以下配置:
-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩 -XX:CMSFullGCsBeforeCompaction=0:上面配置开启的状况下,这里设置多少次FullGc后,对年老代进行压缩
Jconsole,jProfile,VisualVM
Jconsole:jdk自带, 功能简单,可是能够再系统有必定负荷的状况下使用,对垃圾回收算法有很详细的跟踪。
JProfiler:商业软件,须要付费,可是功能强大
VisualVM:JDK自带,功能强大,与Jprofiler相似,推荐
观察内存释放状况、集合类检查,对象树
上面这些调优工具都提供了强大的功能,可是总的来讲通常分为如下几类功能:
一、堆的信息查看(年轻代、年老代、持久代分配)
二、提供即时的垃圾回收功能呢
三、垃圾监控,长时间监控
通常就是根据垃圾回收先后状况对比,同时根据对象引用状况(常见的集合对象引用)分析,基本均可以找到泄漏点。
持久代沾满处理:
一、-XX:MaxPermSize=16m
二、换JDK好比:JRocket
系统内存被沾满:
通常是由于没有足够的资源产生线程形成的,系统建立线程时,除了要在Java堆中分配内存外,操做系统自己也须要分配资源来建立线程。所以,当线程数量大的必定程度之后,堆中或许还有空间,可是操做系统分配不出资源来了,出现异常。
分配给Java虚拟机的内存越多,系统剩余的资源就越少,所以,当系统内存固定时,分配给Java虚拟机的内存越多,那么,系统总共可以产生的线程也就越少,二者成反比。同事,能够经过修改-Xss来减小分配给单个线程的空间,也能够增长系统总共生产的线程数。
java程序内存问题的诊断方法:
一、jstat能够查看垃圾回收状况:jstat -gcutil pid
二、jmap能够将java内存dump出来
三、jstack -l 进程id
四、eclipse插件MAT能够有效的分析内存占用状况
jmap -h
查看jmap的命令参数,帮助查看堆信息