【问题标题】:Java heap out of memory but not really [closed]Java堆内存不足但不是真的[关闭]
【发布时间】:2012-08-30 13:05:43
【问题描述】:

因此,当尝试通过 Turbine servlet 使用 Velocity 呈现页面时出现此错误。问题是我有大量内存,而且 servlet 本身永远不会崩溃。它只是在这个请求上失败了。它尝试渲染的页面可能是 10M。

有人有什么想法/建议吗?

 java.lang.OutOfMemoryError: Java heap space
 java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2271) at
 java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:113) at
 java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
 at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:140)
 at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) at
 sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:282) at
 sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125) at
 sun.nio.cs.StreamEncoder.write(StreamEncoder.java:135) at
 java.io.OutputStreamWriter.write(OutputStreamWriter.java:220) at
 java.io.Writer.write(Writer.java:157) at
 org.apache.velocity.runtime.parser.node.ASTReference.render(ASTReference.java:321)
 at
 org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:94)
 at
 org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:109)
 at
 org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:94)
 at
 org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:271)
 at
 org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:128)
 at
 org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:94)
 at
 org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:271)
 at
 org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:128)
 at
 org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:271)
 at org.apache.velocity.Template.merge(Template.java:296) at
 org.apache.velocity.app.Velocity.mergeTemplate(Velocity.java:492) at
 org.apache.velocity.app.Velocity.mergeTemplate(Velocity.java:461) at
 org.apache.turbine.services.velocity.TurbineVelocityService.executeRequest(TurbineVelocityService.java:455)
 at
 org.apache.turbine.services.velocity.TurbineVelocityService.handleRequest(TurbineVelocityService.java:321)
 at
 org.apache.turbine.services.velocity.TurbineVelocity.handleRequest(TurbineVelocity.java:109)
 at
 org.apache.turbine.modules.layouts.VelocityOnlyLayout.doBuild(VelocityOnlyLayout.java:155)
 at org.apache.turbine.modules.Layout.build(Layout.java:91) at
 org.apache.turbine.modules.LayoutLoader.exec(LayoutLoader.java:138) at
 org.apache.turbine.modules.pages.DefaultPage.doBuild(DefaultPage.java:191)
 at org.apache.turbine.modules.Page.build(Page.java:91) at
 org.apache.turbine.modules.PageLoader.exec(PageLoader.java:136)

JAVA_OPTS= -Xms4096M -Xmn2048M -Xmx13128M

top 下的内存使用量永远不会超过 100M。

【问题讨论】:

  • 它可以重现吗?如果是这样,您能否在呈现页面之前使用 Visual VM(或)JConsole 找出内存详细信息?
  • 非常,每次我尝试生成超过一定大小的页面时都会发生这种情况。我可能可以解决它,但这只是令人沮丧,因为我不明白它为什么或如何发生。我绝对没有用完堆空间(也许是那个线程或其他什么?)。
  • Arrays.java 的第 2271 行是 byte[] copy = new byte[newLength];,但这应该允许最多 Integer.MAX_VALUE - 5 的长度。我不知道这个问题,但我对此发表评论是希望它能激发某人的想法。
  • 你确定 OPTS 被选中了吗?你能在 jconsole 上运行它以确保参数设置正确吗?
  • 你能发布相关的速度模板吗?也许有一些无限循环使生成的文档变得无限大?也许您可以将 OutputStream 重定向到 stdout 只是为了查看在分配失败之前生成了什么?

标签: java heap-memory velocity turbine


【解决方案1】:

我怀疑是您的-Xmn 导致了问题,因为它为年轻代保留了过多的初始堆。我建议在没有这个的情况下运行你的服务器,看看会发生什么。

我的理由是失败发生在ByteArrayOutputStream.grow(),它正在创建一个比现有数组大一些百分比的新数组。大数组(> 512M)直接放入tenured generation,所以如果为young generation预留了太多空间,tenured中可能没有足够的可用空间。

另一种可能是您渲染的模板比您想象的要大得多。虽然最可能的原因是循环,但我在堆栈跟踪中没有看到。

最后,在启动时添加-XX:+HeapDumpOnOutOfMemoryError 选项。如果您的输出数组变得太大,您会在堆转储中看到这一点(使用jhat 检查转储)。

【讨论】:

  • +1 - 好答案。我删除了我的并投了你的票。
猜你喜欢
  • 1970-01-01
  • 2013-09-10
  • 2016-07-04
  • 2014-08-02
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2020-10-25
相关资源
最近更新 更多