2012-09-05 452 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