我最近在我的 JVM 中遇到了一些 OutOfMemoryExceptions,并决定开始使用 MAT 分析我的堆转储,看看我是否可以查明哪些线程正在消耗我的大部分内存。
有趣的是,我查看了系统中的所有线程,发现所有线程的总保留堆约为 4.8G。但是,我的 JVM 的最大堆大小设置为 10G。我可以关联我的堆转储是一个 10G 文件。
这怎么可能?我的总保留大小是否需要接近 10G 限制才能生成 OOM?我在这里误解了什么吗?
根据概述选项卡:
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 中调用的方法的参数,或者其他?