发生OutOfMemoryError之后,我通过IBM Support Assistant的64位内存分析器(运行在Websphere 7.0.23上的J9 VM)处理了生成的堆转储
列出了几个候选泄漏(所有与系统类加载器相关),但其中一个似乎表明StringBuffer中用256值初始化的char[]实际上包含7700万个空字符。
支持助手的堆转储分析结果显示一个字符[77418987]@0xc32***\u0000\u0000\u0000……
这被StringBuffer->PatternLayout->TimeAndSizeRollingAppender 引用
保留的堆检出,每个字符2个字节,数组本身18个字节,总共150+Mbs。
Log4j版本是1.2.16,我们使用simsite TimeAndSizeRollingAppender(尽管我想删除这个依赖项)。
这可能是Support Assistant的误报吗?或者有没有某种方法可以让char[256]变成堆上的char[770000000+]?
默认情况下,WebSphere会生成一个PHD文件来响应OOM事件。需要注意的一点是,这些转储包含有关堆中对象及其引用的信息,但不包含存储在属性和数组(基元类型)中的实际数据。这就是为什么内存分析器只显示零的原因。要获得有关根本原因的更多信息,您应该将WebSphere配置为创建系统转储。这将允许您查看数组中的数据,并应该为您提供有关正在发生的事情的提示。
以下链接解释了如何做到这一点:
http://pic.dhe.ibm.com/infocenter/isa/v4r1m0/topic/com.ibm.java.diagnostics.memory.analyzer.doc/producing.html
对于256与77000000+的问题:256只是StringBuffer的初始容量。当附加数据时,它会根据需要自动增长。