发生 OutOfMemoryError 后,我通过 IBM Support Assistant 的 64 位内存分析器(在 Websphere 7.0.23 上运行的 J9 VM)处理了生成的堆转储
列出了几个候选泄漏(所有系统类加载器相关),但其中之一似乎表明 StringBuffer 中用值 256 初始化的 char[] 实际上包含 7700 万个空字符。
来自支持助手的堆转储分析结果显示 char[77418987] @ 0xc32***\u0000\u0000\u0000.......
这是由 StringBuffer -> PatternLayout -> TimeAndSizeRollingAppender 引用的
保留堆 checkout ,每个字符 2 个字节,数组本身 18 个字节,总共 150+ Mbs。
Log4j 版本是 1.2.16,我们使用 simonsite TimeAndSizeRollingAppender(尽管我想删除此依赖项)。
这可能是支持助理的误报,还是有某种方法可以使 char[256] 变成堆上的 char[77000000+]?
最佳答案
默认情况下,WebSphere 生成 PHD 文件以响应 OOM 事件。您需要注意的一件事是,这些转储包含有关堆中的对象及其引用的信息,但不包含存储在属性和数组(基本类型)中的实际数据。这就是内存分析器仅显示零的原因。要获取有关根本原因的更多信息,您应该配置 WebSphere 以创建系统转储。这将允许您查看数组中的数据,并提示您正在发生的情况。
以下链接说明了如何执行此操作:
对于 256 与 77000000+ 的问题:256 只是 StringBuffer 的初始容量。当添加数据时,它会根据需要自动增长。
关于java - StringBuffer char[] 似乎超出堆转储中的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22067124/