调试java.lang.OutOfMemoryError 异常的最佳方法是什么?
OutOfMemoryError 在消息描述中描述错误类型。您必须检查错误消息的描述才能处理异常。
内存不足异常有多种根本原因。有关详细信息,请参阅 oracle 文档page。
java.lang.OutOfMemoryError: Java heap space:
原因:详细信息Java heap space表示无法在Java heap中分配对象。
java.lang.OutOfMemoryError: GC Overhead limit exceeded:
原因:详细信息“GC Overhead limit exceeded”表示垃圾收集器一直在运行,Java 程序进展缓慢
java.lang.OutOfMemoryError: Requested array size exceeds VM limit:
原因:详细消息“请求的数组大小超过 VM 限制”表明应用程序(或该应用程序使用的 API)试图分配大于堆大小的数组。 p>
java.lang.OutOfMemoryError: Metaspace:
原因: Java 类元数据(Java 类的虚拟机内部表示)分配在本机内存(这里称为元空间)中
java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?:
原因: 详细信息“request size bytes for reason. Out of swap space?”似乎是OutOfMemoryError 异常。但是,当从本机堆分配失败并且本机堆可能接近耗尽时,Java HotSpot VM 代码会报告此明显异常
java.lang.OutOfMemoryError: Compressed class space
原因: 在 64 位平台上,指向类元数据的指针可以用 32 位偏移量表示(使用 UseCompressedOops)。这由命令行标志 UseCompressedClassPointers 控制(默认开启)。
如果使用UseCompressedClassPointers,则可用于类元数据的空间量固定为CompressedClassSpaceSize。如果UseCompressedClassPointers 所需的空间超过CompressedClassSpaceSize,则会抛出带有详细压缩类空间的java.lang.OutOfMemoryError。
注意: 类元数据不止一种——类元数据和其他元数据。只有类元数据存储在CompressedClassSpaceSize 界定的空间中。其他元数据存储在 Metaspace 中。
我们应该使用堆转储文件吗?我们应该生成 Java 线程转储吗?到底有什么区别?
是的。您可以使用此堆堆转储文件来调试问题,使用诸如visualvm 或mat 之类的分析工具
您可以使用线程转储来进一步了解线程的状态。
请参阅此 SE 问题以了解不同之处:
Difference between javacore, thread dump and heap dump in Websphere
生成线程转储的最佳方法是什么? kill -3(我们的应用程序在 Solaris 上运行)是杀死应用程序并生成线程转储的最佳方式吗?有没有办法生成线程转储但不杀死应用程序?
kill -3 <process_id> 生成线程转储,此命令不会杀死 java 进程。