JVM配置参数
-Xms
含义:初始堆
默认:物理内存的1/64(<1GB)
备注:默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制(MinHeapFreeRatio参数可以调整)
含义:最大堆
默认:物理内存的1/4(<1GB)
备注:默认空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制(MaxHeapFreeRatio参数可以调整)
-Xmn
含义:年轻代(1.4 or later)
备注:注意:此处的大小是(eden + 2 survivor space),与jmap -heap中显示的New gen是不同的。整个堆大小=年轻代大小 + 老年代大小。增大年轻代后,将会减小老年代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8,默认占整个堆的1/3。
含义:每个线程的堆栈大小
备注:JDK5.0以后每个线程堆栈大小为1M。根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。一般小的应用,如果栈不是很深,应该是128k够用的,大的应用建议使用256k。
这个选项对性能影响比较大,需要严格的测试。
默认:物理内存的1/64
含义:设置持久代最大值
默认:物理内存的1/4
含义:老年代与年轻代(包括Eden和两个Survivor区)的比值
备注:-XX:NewRatio=4表示年轻代与老年代所占比值为1:4,年轻代占整个堆栈的1/5,Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。
含义:Eden区与Survivor区的比值
备注:设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
-XX:MaxTenuringThreshold
含义:垃圾最大年龄
备注:如果设置为0的话,则年轻代对象不经过Survivor区,直接进入老年代。对于老年代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代即被回收的概率该参数只有在串行GC时才有效。
含义:通过参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照
备注:用eclipse,Help -> eclipsemarketplace -> Memory Analyzer安装分析工具打开,或者用jdk自带jvisualvm打开进行分析
JVM分析工具
JVM GUI
jdk 1.7以后自带的三个JVM GUI监视工具:
1. jconsole
2. jmc
3. jvisualvm
JVM 分析命令
1. jps(Java Virtual Machine Process Status Tool)
查看本地运行着的java程序,并显示他们的进程号。
(1) -l 输出应用程序main class的完整package名或者应用程序的jar文件完整路径名
(2) -v 输出传递给JVM的参数
(3) -m 输出传递给main方法的参数,在嵌入式jvm上可能是null
> jps -l2. jmap
打出一个dump文件,分析 Heap Dump 的工具都可以获取 Heap Dump 文件。
比如:jdk 自带的工具 jvisualvm。其它工具:Eclipse memory analyzer(jmat)、JProfiler 等。
>jmap -dump:live,format=b,file=/path/heap.hprof {pid}3. jinfo
输出并修改运行时环境属性。
>jinfo {pid}4. jstack
输出线程的调用栈及是否死锁属性,主要用于检查JVM的假死、死锁等。
>jstack -F {pid}5. jstat
监视JVM内存内的各种堆和非堆的大小及其内存使用量。
>jstat -gcutil -h3 {pid} 500 6 :-h3每三行显示一下标题,每500毫秒打印一次,一共打印6次问题定义
内存溢出(OOM):JVM可用内存不足
内存泄漏(Memory Leak):JVM始终无法收回的内存
持续的内存泄漏最终会导致内存溢出
内存泄漏/溢出、程序卡死一般步骤:
1. jps -l 查进程号
2. 在线查看(如果是windows环境可以用jmc、jconsole、jvisualvm直接分析)
(1)观察内存及GC情况
>jstat -gcutil -h10 {pid} 1000 -1
特别关注FGC的次数以及老年代O的使用情况,如果居高不下,FGC次数累计较快,说明距离溢出不远了...
(2)直接查看线程快照,检查停在了哪类线程的哪个方法
>jstack -F {pid}
(3)打印存活的实例情况、线程快照
>jmap -dump:live,format=b,file=/heap.hprof {pid}
打出一个dump文件,用jvisualvm或者Eclipse memory analyzer(jmat)、JProfiler 等进行分析,数量最多的实例是哪些。
3. 添加运行参数,溢出时打印快照
>-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=F:/
运行程序,当溢出时打印堆栈快照,再进行分析内存及线程
注意:如果是卡死,重点分析线程;如果是溢出/泄漏,重点分析内存占用情况。