Java内存溢出分析
- java内存分类
java内存分为堆内存和非堆内存。
1) 非堆内存指的是加载class文件所使用的内存,使用permsize相关参数可以配置其大小,一般程序使用几百兆就足够了;
2) 堆内存是垃圾回收器负责回收的内存,分为新生代和老年代,一般内存溢出问题都是老年代内存持续增大,无法回收导致。新生代内存中的对象一般都是朝生夕死的,很快就可以被回收,如果新生代中对象的生命周期过长、或对象过大时,新生代对象会转移到老年代中。
2.内存查看工具
可以使用jdk自带的jconsole工具查看内存使用情况。
进入jdk所在目录,输入命令jconsole,出现如下界面
3.内存分析工具
如果程序运行不稳定,可以通过生成dump文件分析内存中大量存在的类对象,进而分析程序哪里写的不合理。分析dump文件工具可使用eclipse的memory analysis。
dump文件生成命令:jmap -dump:format=b,file=文件名 [pid]
使用memory analysis打开dump文件如下截图,截图反映SearchGroup对象相关代码书写有问题,占用内存过高:
一般导致内存溢出的原因:
1)数据库查询语句没有动态传参;
2)导出excel文件未使用流写入方式;
3)使用static变量导致对象无法回收等。
页面耗内存,是因为使用了一个tiles框架,<tiles:put name="content" type="String">这种写法会导致页面缓存到jvm堆内存中;<tiles:put name="content" value="/WEB-INF/pages/com//order/layout/left_down_app-put.jsp"/>这种写法不会
cpu100%问题,页面http请求pendding状态:
使用的是hibernate3.1.2的包,此版本存在bug,get有synchronize方法,put等其他没有,多线程访问时发生循环i值被反复更改,无法跳出循环;升级到3.3.0-GA版本解决,但3.3.0版本count、sum sql语句返回的值类型由Integer更改为Long,需修改程序代码