1

最近、JVM で OutOfMemoryExceptions が発生するようになりました。MAT を使用してヒープ ダンプの分析を開始し、メモリの大部分を消費しているスレッドを特定できるかどうかを確認することにしました。

興味深いことに、システム内のすべてのスレッドを調べたところ、すべてのスレッドの保持ヒープの合計が約 4.8G であることがわかりました。ただし、JVM の最大ヒープ サイズは 10G に設定されています。ヒープ ダンプが 10G ファイルであることを関連付けることができます。

そんなことがあるものか?OOM を生成するには、保持するサイズの合計が 10G の制限に近づく必要があるのではないでしょうか? ここで何か誤解していますか?

[概要] タブによると:

Size: 6.6 GB Classes: 15.7k Objects: 164.1m Class Loader: 690

正確なエラー メッセージは次のとおりです。

java.lang.RuntimeException: java.lang.OutOfMemoryError: Java heap space
    at business.service.AuditImportHelper.importAuditStream(AuditImportHelper.java:580)
    at business.service.AuditImportHelper.importAuditTrailFiles(AuditImportHelper.java:372)
    at business.service.AuditImportHelper.doImport(AuditImportHelper.java:171)
    ....
    ....
    ....
    at org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:170)
    at org.jboss.mq.SpySession.run(SpySession.java:323)
    at org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:237)
    at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
    at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
    at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:743)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2367)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:535)
    at java.lang.StringBuffer.append(StringBuffer.java:322)
    at java.io.BufferedReader.readLine(BufferedReader.java:363)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at business.service.AuditImportHelper.importAuditStream(AuditImportHelper.java:457)
    at business.service.AuditImportHelper.importAuditTrailFiles(AuditImportHelper.java:372)

ヒープ ダンプを見ると、コピーしようとしている配列 (char[]) がかなり大きい (1G) ことがわかります。JVM は、実行しようとするときにスペース全体を事前に割り当てますか、copyOfそれとも要素ごとに割り当てますか?

メソッドに渡されるパラメーターを調べようとしていますがcopyOf()、MAT でそれらを表示するかどうか/どのように表示するかはわかりません。MAT で呼び出されているメソッドのパラメーターをスレッド ビューなどで確認する方法はありますか?

4

0 に答える 0