2012-09-05 230 views
0

因此在尝试通过Turbine servlet使用Velocity渲染页面时出现此错误。事情是我有很多内存,并且servlet本身从不崩溃。它只是在这个请求失败。它试图呈现的页面可能是10M。Java堆内存不足

任何人有任何想法/建议吗?在顶部

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

内存使用从未得到上述100M。

+1

它可重现吗?如果是这样,你能在渲染页面之前使用Visual VM(或)JConsole找出内存细节吗? – kosa

+0

非常,每当我尝试生成超过特定大小的页面时都会发生。我大概可以解决它,但这只是令人沮丧,因为我不明白为什么或如何发生。我绝对没有用完堆空间(可能是为那个线程或其他东西?)。 –

+0

Arrays.java的第2271行是'byte [] copy = new byte [newLength];',但是应该允许长度为'Integer.MAX_VALUE - 5'。我不知道这个问题,但我对此发表评论,希望它能引发某人的想法。 – Vulcan

回答

2

我怀疑你的-Xmn是由于为年轻一代保留了一大堆初始堆而造成的问题。我建议在没有这个的情况下运行你的服务器,看看会发生什么。

我的推理是,ByteArrayOutputStream.grow()发生故障,这是创建一个比现有的一个百分比大的新数组。大型数组(> 512M)直接进入终身代,所以如果太多空间留给年轻一代,可能没有足够的可用空间。

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

最后,在启动时添加-XX:+HeapDumpOnOutOfMemoryError选项。如果你的输出数组增长过大,你会在堆转储中看到这个(使用jhat来检查转储)。

+0

+1 - 很好的答案。我删除了我的并投了你的票。 – duffymo