公司有个项目在最近连续几天又报内存溢出的异常。我被指定协助项目组解决这个问题。内存溢出问题往往最难解决,从哪里下手呢?先从调研开始,与项目组的技术人员沟通之后了解到:
1、 受机器条件所限只能将jvm的最大内存设为2048M。所以只能从其它方面想办法。
2、 最近一年多在运行一段时间之后总是报内存溢出的错误。考虑过很多办法也没有从根本上解决这个问题,最后之好写了一个脚本,在每天晚上12点钟重新启动webLogic 用这种不是办法的办法解了燃眉之急。
3、 检查代码中静态变量的使用情况,特别是集合类型的静态变量,不过该项目代码量非常大,总共有10多个部署的war包,短时间内还是很难完成这项检查工作,而且这一年多来该项目组也对代码进行了很多的优化工作,他们认为静态变量的问题不大。
4、 项目组怀疑是因为部署的war包太多,每个war包中引入的jar包数量都在200M左右,10多个war包中的jar大小累加起来都超过2G了,他们认为是因为jar本身在装入时占用了太多的内存。
不过我的直觉告诉我,jar本身占用的内存应该与程序运行区分配的内存是无关的,因为以上编C++程序时就是这样的,程序区与数据区是分开的,程序区不是我们要考虑的。但是我猜测,如果某个jar中的缓存了一份内存,而且这个jar包又分别被这10多个war包引用的话,那么内存的占用量就会放大了10倍。不过我当时怀疑的是我们自己开发的公用jar包,结果花了很大的时间最找我们自己公用jar包中的静态变量的问题,不过收获不大。
后来使用ha28分析了三个heapdump文件样本,发现每个样本中BeanHelper占用的内存都在100M-400M之间