新建Java对象时会在JVM的Heap中分配内存,对象不可达时其内存会被JVM GC回收,
可是当Heap中没有多余内存可供分配时,就会报OutOfMemory错误(如下简称OOM):java
严重: Unexpected death of background thread ContainerBackgroundProcessor[StandardEngine[Catalina]] java.lang.OutOfMemoryError: Java heap space at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1379)
解决方式很简单——加大Heap:数据库
set JAVA_OPTS=-Dfile.encoding=UTF-8 -Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m
可是这不是根本解决之道:apache
OOM一般是因为内存被不合理的使用,好比:tomcat
可是OOM错误不像其它报错那样容易排查,由于没有Stacktrace可供查看。
要找出内存被过分使用的缘由,必须去“看”OOM时JVM Heap中的情况——哪些Class的Object占用了过多的内存——Profillingjvm
Oracle JDK已经自带了很好用的Profilling工具:工具
setclasspath.bat中添加
【set CATALINA_OPTS=-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=1010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false】
命令行【jconsole】打开界面,链接tomcat进程,远程端口1010,能够查看内存水位、线程池等。性能
jconsole能看到的信息比较有限,没法排查出耗掉内存的元凶,
还需借助jmap来把JVM Heap“转储”到文件,而后经过jvisualvm来analysis:
当你的服务OOM了,找到jvm进程id,而后命令行【jmap -heap:format=b pid】生成heap.bin;
而后命令行【jvisualvm】打开分析器,加载heap.bin,查看内存状态,看看是哪一个家伙把内存吃光了;
以下图:ParamTreePaymentTerm有3852个实例,消耗了593K的Heap内存:优化
根据问题缘由对应优化代码,并按照须要给jvm分配相应内存。spa
经常使用 Java Profiling 工具的分析与比较参考http://www.oschina.net/question/12_10515.net