java - 内存分析器工具:ParseHeapDump.sh - 应用程序错误:OutOfMemory 请求的新长 [2,147,483,640] 长度超过 2,147,483,639 的限制
问题描述
我正在尝试分析远程机器上的 200GB 堆转储。堆转储是通过 visualVMs 的“创建堆转储”按钮创建的。即使使用 Xmx300GB ( "$(dirname -- "$0")"/MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx300g -XX:-UseGCOverheadLimit
) 执行它也会导致 MAT 崩溃并出现以下错误:
eclipse.buildId=unknown
java.version=11.0.3
java.vendor=Oracle Corporation
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=en_US
Framework arguments: -application org.eclipse.mat.api.parse ./tmp/heapdump-1577977940574.hprof
Command-line arguments: -os linux -ws gtk -arch x86_64 -consolelog -application org.eclipse.mat.api.parse ./tmp/heapdump-1577977940574.hprof
!ENTRY org.eclipse.osgi 4 0 2020-01-06 16:25:11.593
!MESSAGE Application error
!STACK 1
java.lang.OutOfMemoryError: Requested length of new long[2,147,483,640] exceeds limit of 2,147,483,639
at org.eclipse.mat.parser.index.IndexWriter$Identifier.add(IndexWriter.java:91)
at org.eclipse.mat.hprof.HprofParserHandlerImpl.reportInstance(HprofParserHandlerImpl.java:588)
at org.eclipse.mat.hprof.Pass1Parser.readPrimitiveArrayDump(Pass1Parser.java:590)
at org.eclipse.mat.hprof.Pass1Parser.readDumpSegments(Pass1Parser.java:366)
at org.eclipse.mat.hprof.Pass1Parser.read(Pass1Parser.java:175)
at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:80)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.parse(SnapshotFactoryImpl.java:222)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.openSnapshot(SnapshotFactoryImpl.java:126)
at org.eclipse.mat.snapshot.SnapshotFactory.openSnapshot(SnapshotFactory.java:145)
at org.eclipse.mat.internal.apps.ParseSnapshotApp.parse(ParseSnapshotApp.java:134)
at org.eclipse.mat.internal.apps.ParseSnapshotApp.start(ParseSnapshotApp.java:106)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:656)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:592)
at org.eclipse.equinox.launcher.Main.run(Main.java:1498)
at org.eclipse.equinox.launcher.Main.main(Main.java:1471)
文件可能已损坏,还是太大而无法分析?
解决方案
根据此评论,您很可能遇到了 Memory Analyzer 的已知限制:
“Memory Analyzer 的架构限制为 2^31 - 3 个对象,当前限制为 2^31 - 8 = 2,147,483,640 个对象,但尚未使用那么多对象进行测试。当前记录是一个 48GB 的堆转储文件,包含 948,000,000对象,它是使用运行 58GB 堆的内存分析器打开的。”
另请参阅https://dev.eclipse.org/mhonarc/lists//mat-dev/msg00324.html
无论堆大小有多大,Java 都不允许创建大于Integer.MAX_VALUE - 5
2,147,483,639的数组。
您可以尝试下载最新的 Memory Analyzer 版本,看看限制是否有所改善。
推荐阅读
- java - 使用我的 Spring Boot 应用程序运行 Azure Application Insights 代理时,我不断收到 IllegalStateException
- python - django 数据库错误错误的打印选择字段
- nlp - 从文本中提取难词
- r - 基本问题:如何为绘图中的线条添加颜色
- django - 如何限制 django 频道房间中的客户端数量
- javascript - 如何为 Firebase DB 设置安全规则,以使用户无法向 DB 发出未经授权的请求?
- python - 如何在 Python 中检查大于 N 行的函数
- r - 使用 dplyr::filter() 删除 NA
- react-native - 返回按钮以纠正平面列表的位置
- google-sheets - 谷歌表格“如果”从列而不是单元格进行验证