我的 Java 程序抛出一个 OutOfMemoryError
。如何调试和修复此问题?
许多 Java 新手都难以应对 OutOfMemoryError
。这是尝试创建一个规范问题,以回答有关 OutOfMemoryError
的最常见问题。我正在创建这个新问题,而不是改编之前关于 OutOfMemoryError
的众多问题之一,因为这些问题及其答案与一个人遇到的特定问题紧密相关.
这个问题不同于general advice on debugging exceptions因为问题的原因并不总是在调用堆栈上,需要具体的建议。
最佳答案
OutOfMemoryError
是 Java 虚拟机 (JVM) 抛出的异常,因为它需要为(新)对象分配内存,但该对象可用的内存不足。 JVM 将首先尝试通过 running the garbage collector 释放死对象使用的内存。 .
由于 OutOfMemoryError
是 VirtualMachineError
,因此允许 JVM throw it at any time , 虽然它必须 try to release memory through garbage collection first .
但是,在实践中,它很可能会从试图创建无法为其分配内存的对象的 new
语句中抛出。因此,您应该首先检查与异常关联的堆栈跟踪,以获取有关问题原因的线索,as you would for any other exception .
- 如果尝试分配数组(例如
int[] values = new int[n]
)时抛出异常,原因可能是您试图创建一个过大的数组数组(n
太大)。您是否在计算所需数组大小时出错? - 如果异常是由于尝试在其他人编写的容器类的方法中分配数组而抛出的,原因可能是您的代码要求容器存储过多的东西。
ArrayList.reserve(int)
和HashMap(int)
等方法必须分配存储以供将来使用。您在计算所需容器尺寸时是否犯了错误? - 如果异常是从循环内部抛出的,原因可能是代码循环了太多次。您的循环终止条件是否正确?如果它是一个
for
循环,你是否要求它循环正确的次数?
如果堆栈跟踪没有提供足够的线索,您可以尝试使用堆分析器。这是一个监控程序,可让您在程序运行时检查用于对象的内存,或在程序退出时检查写入的堆转储。它可以提供有关存储在内存中的对象的大小、数量和类别的信息。
JVM 有一个 finite amount of memory提供给它。您可能会得出结论,您的程序运行正常,只是需要比可用内存更多的内存才能运行。如果您没有明确告诉 JVM 使用多少内存,大多数实现将选择 sensible default。数量取决于您的计算机拥有的 RAM 数量,但该数量对于您的程序来说可能太小了。 JVM 的命令行选项可以控制可用的内存量。对于大多数 JVM 实现,这些选项中最重要的是 -Xmx
。和 -Xms
。
关于java - 什么是 OutOfMemoryError 以及如何调试和修复它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55230394/