一、内存不足可能由以下原因造成:
1。配置参数指定的JVM堆最大值太小
2。内存碎片问题,即虽然所有空闲内存的总和大于需要申请的内存,但是,由于这些内存不是连续的(可能由于某些内存快不可移动)而无法分配; 可能由于存在固定对象或者大对象问题,缓存大小问题
3。内存泄露:即由于应用程序的非正常的申请越来越多的内存对象导致最终所有的内存空间都被用完。
二、内存泄露的可能原因包括:
1。向集合中插入而没有删除
2。未邦定的缓存
3。未调用的侦听器方法
4。无限循环
5。过多的会话对象没有及时的删除
6。数据结构的设计问题等。
三、IBM JDK5.0 提供了4种内存回收策略,可以通过设置 -Xgcpolicy配置参数来指定使用哪一种策略:
1。optthruput:是默认策略,采用标记-清除-整理收集器,针对吞吐量进行优化。然而,由于标记栈大小固定并且无法设置,当堆中有大量对象生成时,显然标记栈会不够用,标记栈溢出(mark stack overflow)将会产生。 它不使用并发标记。如果用户没有内存回收时系统暂停时间过长问题,就可以保持这个默认参数。
2。optavgpause: 会启用同步标记,针对停顿时间进行优化,这将减少暂停时间并且让暂停时间长度在堆空间占用率上升的时候更稳定。然而,这个参数将减少系统吞吐量大约5%,当然这一数值将因程序不同而有一定差异。
3。gencon :分代并发,从IBM JDK 1.5.0开始加入。类似于SUN的JVM的分代收集,将并发标记和传统的垃圾回收机制总和使用的策略,用于奖内存回收时的在哪听时间最小化。
4。subpoo:不使用并发标记,但是,使用一种该井的内存分配算法用来获得更好的性能。这种策略在系统处理器多余16个的时候才能看出性能提升的效果。并且只适用于AIX,Linux PPC, ZSeries, Z/OS和i5/OS系统。
四、内存使用问题分析流程图
1。GC前的空闲空间(Free Space before AF)
2。GC后的空闲空间(Free Space after AF)
3.。AF:allocate faults
五。内存泄露问题实例
1。在WAS控制台增加JVM的如下定制属性:
IBM_HEAPDUMP=TRUE
IBM_HEAP_DUMP=TRUE
IBM_HEAPDUMPDIR=<heapdump输出文件目录>
IBM_HEAPDUMP_OUTMEMORY=TRUE
IBM_JAVADUMP_OUTOFMEMORY=TRUE
IBM_JAVA_HEAPDUMP_TEXT=TRUE
如果没有设孩子IBM_HEAPDUMPDIR,默认的输出路径就是应用服务器的根目录
保存修改后需要重新启动应用服务器。在UNIX平台需要获取应用服务器进程的进程PID。当需要产生heapdump文件,在命令行输入 kill -4 PID
如果是Windows平台,没有kill命令,需要通过WAS应用服务器的命令行控制台进行,如下所示:
<WAS_HOME>\profiles\server1\bin>wsadmin.bat
wsadmin>set jvm [$AdminControl completeObjectName type=JVM,process=server1,*]
wsadmin>$AdminControl invoke $jvm dumpThreads