很多tomcat进程退出(或者进程假死),都是由于频繁的抛出OutOfMemeoryError导致的。
为了让tomcat退出前或者发生OutOfMemeoryError时自动dump堆栈信息,方便事后排查问题,我们可以做如下操作:
1、 在tomcat启动参数中加入两个参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/home/tomcat/domains/server2/oom.hprof
2、 重启tomcat
参数说明
(1)-XX:+HeapDumpOnOutOfMemoryError 表示当JVM发生OOM时,自动生成DUMP文件。
(2)-XX:HeapDumpPath=存储文件/目录 表示生成DUMP文件的路径
诊断内存溢出是一个有难度的事情,可以在生产环境试一试下面的参数,在发生内存溢出OutOfMemoryError时做HeapDump并保存到文件,然后分析该文件看是否能查到蛛丝马迹。
set JAVA_OPTS=-Xms100m -Xmx192m ^
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:\jakarta-tomcat\webapps
Java Heap Dump文件格式是一个HPROF二进制格式,需要特殊的工具才能进行分析,而这个文件通常都比较大,如果你的Heap Dump文件超过了几百MB,那就不要再寄希望于jhat了,因为jhat需要数倍于dump文件的内存。这个时候你可以用MAT(Memory Analyzer),用MAT你可以在有2GB可用内存的机器上分析大约1GB左右的Dump文件。
设置启动参数:
下面只是添加参数的方法,具体参数视情况而定
linux环境:
修改catalina.sh添加如下参数,然后保存。
JAVA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+PrintGCDetails"
注意:linux更改这个文件后,tomcat可能会启动不了,报找不到这个文件,这时候就要看看这个文件权限。linux修改了问加你要重新赋权限。
如果是windows环境
windows下catalina.bat中完整代码如下:
set JAVA_HOME=E:\jdk1.6.0_31 set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+PrintGCDetails set JAVA_OPTS=%JAVA_OPTS% -server -verbose:gc
Tomcat启动参数总结
目前见到的tomcat的一些使用参数,再遇到继续补充
-Xmx1g
设置tomcat的最大使用内存,32位系统因为系统原因有最大限制,64位系统则受限于计算机的物理内存。
-Xmx1g
设置tomcat的初始内存大小,此值可设置与-Xmx一致,以免jvm在每次垃圾回收之后重新分配内存。
-Xmn512m
设置jvm的年轻带大小。
-XX:PermSize64m
设置jvm的永久带大小
-XX:MaxPermSize64m
设置jvm永久区的最大大小,整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss128k
设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线 程数还是有限制的,不能无限生成,经验值在3000~5000左右。
-XX:SurvivorRatio=6
设置年轻带中Eden区和Survivor区的比例大小,比例为6,则每个Survivor区占年轻带的1/8。系统默认是8
-XX:NewRatio
设置年轻带和老年代的比例大小。
-XX:MaxTenuringThreshold
设置最大的老年代的年龄,系统默认是15,对象在经历15次年轻带的GC后才会进入老年带。这个值设置小时对老年代较多应用来说可以提高效率,这个值设置较大时,可以增加对象的存活时间、提高对象被回收的几率。
-Xnoclassgc
关闭CLASS的垃圾回收功能,就是虚拟机加载的类,即便是不使用,没有实例也不会回收。如果一个类20分钟还没有使用,虚拟机会卸载这个类。如果这个类再次使用,虚拟机会重新加载这个类,由于虚拟机加载类包含了 IO和内存分配的操作,因此加载时会对性能有所影响。对于一般应用,这个参数对性能影响不大。
-XX:+DisableExplicitGC
标志自动将System.gc()调用转换成一个空操作,就是应用中调用System.gc()会变成一个空操作。最主要的原因是为了防止某些手贱的同学在代码里到处写System.gc()的调用而干扰了程序的正常运行吧。有些应用程序本来
可能正常跑一天也不会出一次full GC,但就是因为有人在代码里调用了System.gc()而不得不间歇性被暂停
但是也有相应的缺点:应用大量使用了NIO的direct memory时,会抛出异常:java.lang.OutOfMemoryError: Direct buffer memory
-XX:+PrintTenuringDistribution
增加GC日志的输出,输出的方式是观察在每一个岁数上面,对象的存活的数量,以及其增减情况,以及HotSpot VM计算的任期阀值是不是等于或者近似于设定的最大任期阀值。
-XX:+HeapDumpOnOutOfMemoryError
表示当JVM发生OOM时,自动生成DUMP文件。
-XX:+UseParallelGC
指 定在 New Generation 使用 parallel collector, 并行收集 , 暂停 app threads, 同时启动多个垃圾回收 thread, 不能和 CMS gc 一起使用 . 系统吨吐量优先 , 但是会有较长长时间的 app pause, 后台系统任务可以使用此 gc
-XX:ParallelGCThreads=8
配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
-XX:+UseParallelOldGC
ParallelOld是并行收集器,和SerialOld一样,ParallelOld是一个老年代收集器,是老年代吞吐量优先的一个收集器。这个收集器在JDK1.6之后才开始提供的,在此之前,ParallelScavenge只能选择SerialOld来作为其老年代 的收集器,这严重拖累了ParallelScavenge整体的速度。而ParallelOld的出现后,“吞吐量优先”收集器才名副其实!
-XX:+PrintClassHistogram
打印出实例的数量以及空间大小
-verbose:gc
查看虚拟机中内存回收情况
-XX:+PrintGCDetails
打印详细的GC日志
-XX:+PrintGCTimeStamps
输出GC的时间戳
-XX:+PrintHeapAtGC
打印堆内存在GC时更详细的信息
-Xloggc:../log/battleGC.log
GC文件的输出目录
还没有评论,来说两句吧...