这两天我们的开发服务器,不断的内存溢出。经过对内存溢出文件的分析,发现,大部分都是HashMap和Object对象太大导致的,但是分析不出来,具体代码里面哪里导致的。所以请各位大神,帮忙指点一下。
dump文件都2G+,没有办法上传,所以把dump文件分析后的结果,上传一下,请各位帮忙看一下,是不是可以初步断定,从javacore文件上看到的[querypolicylist/hs/NBQueryUnsignUccHSImpl.queryPolicyList()]导致的。但是,不知道分析的是否正确。
dump分析文件如下:
图1:
图2:
图3:
图4:
主要是图4中,大部分的问题都是【java/lang/Object】,但是,查看详细内容【图3】,并分析不出来原因。而图2中,排第一的是hashmap,我觉得,这个在GC回收的时候,自然就会进行释放。可是Object,这个问题,就难住了。以往分析的时候,大部分会发现自己的代码所导致的。这次,在dump分析文件中,前6个根本没有。
所以,转过头看javacore文件,发现里面有自己代码的信息。但是又不敢确定是否是它导致的,所以想向大家确认一下,大家帮忙分析并指点指点。
已经分析6个dump文件。都在这个问题。
附件:
error捕获1.rar (14.1 MB)
server.rar (5.47 KB)
[querypolicylist/hs/NBQueryUnsignUccHSImpl.queryPolicyList()]
怀疑返回没有带分页的大量数据记录,导致OOM的,分析一下代码与数据库表里的记录大小。
日志上传好了,发出来看看。
收起1. 你物理机的物理内存多大?你的最大JVM分配了18G!而且可以通过javacore看出,而且18G的JVM都被完全使用,object对象使用了99%的内存,而这种现象日常应用中很大的概率是因为应用从数据库中获取数据保存到集合中便于以后遍历或者大批量文件读写缓存到jvm中导致的,当然也可能是其他原因。
2. 其实当时已经OOM了([16-11-9 11:57:01:598 CST] 0000007e SystemErr R Java heap spacejava.lang.OutOfMemoryError at java.lang.OutOfMemoryErrorjava.lang.OutOfMemoryErrorjava.lang.OutOfMemoryError: ),但你确认下是否产生了heapdump,如果没有生成建议在配置一下,然后强制OOM时生成heapdump,这样可以通过heapdump看出大概的内存使用情况(具体方法你可以网上查下,或者我稍后再找到官网的链接给你,但建议自己在官网找,然后直接实践更好)。
3. 根据javacore中可以看出有9个线程执行了如下的方法调用,同时这九个线程的栈深是最深的几个,也就是说这几个线程占用JVM内存的时间越久,值得怀疑,建议查查性能,是否跟司令所说的一样,返回没有带分页的大量数据记录:
at com/nci/tunan/nb/impl/unsign/exports/inbqueryunsignucc/querypolicylist/hs/NBQueryUnsignUccHSImpl.queryPolicyList(NBQueryUnsignUccHSImpl.java:71) 忽略了前面的通用方法调用,主要看这一句。。。 |
4. 根据javacore来看,你的线程最大配置了350,而javacore中直到内存溢出,实际上内存并不多,没超过100,请考虑设置这么大有没有必要?
5. 还是我以前回答你的问题一样,JVM设置太大,并不见得性能就会上升,建议缩小。
6. 关于GC的策略问题,它确实新生和老生带都为串行也就是单个线程进行垃圾回收,但垃圾回收的前提是,jvm认为该对象不存在引用到该释放的时候才释放,但你的对象是一只霸占jvm,说明jvm认为它不应该释放,所以你再怎么调节都是没用的,主要问题没解决,jvm参数都是根据实际情况慢慢调整,他是一个漫长的过程,不是一下子就能调整好的(https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/)。
7. 可以适当加上-XX:MaxPermSzie这个参数,堆外内存,用来存放持久化对象,打开GC详细回收并将GC日志循环输入到指定文件。
8. 线程数和线程池连接数确实是遵循漏斗原则,你关于线程数和数据源连接数的看法是正确的。(http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1106_zhuxl_websphereenhancement/1106_zhuxl_websphereenhancement.html)
收起补充一下,附件是我当前was服务器的server.xml配置信息。
烦请大神们帮忙看看,当前was的配置信息。应该如何优化。
目前我所理解的调优方案如下:
1、调整JVM的内存大小,4~8个G为理想大小。
2、调整GC的回收方式,推荐为分代并发。
3、调整数据库连接数。
4、调整线程数。且线程数要比数据库连接数大25%。
除此之外,还需要关系那些参数?
收起图片是今天出现的问题,服务器刚部署不到10分钟,就出现内存迅速增长,GC回收也没有办法。JVM让配置人员调到18G。我的观点是内存调多大都解决不了代码里面的bug。
可是分析了半天,也强制生成javacore文件,最后只看到时线程挂起的问题。并且在JConsole的output日志中,发现【java.net.SocketTimeoutExeption:Read timed out】,我把线程的响应时间调整到60000ms,也没有解决此问题。
我现在初步判断,还是代码里面的异常导致的,查询多个210W+ 的数据导致的。
附件【error捕获1】文件中,有was的当时log日志,以及强制生成的javacore文件。
请各位大神帮忙分析一下。谢谢!
收起