我的 Java 程序抛出了一个OutOfMemoryError
。我该如何调试并解决这个问题?
许多 Java 新手都在努力应对OutOfMemoryError
。这是创建一个规范问题的尝试,该问题将回答有关某个问题的最常见问题OutOfMemoryError
。我正在创建这个新问题,而不是改编之前关于某个问题的众多问题之一OutOfMemoryError
因为这些问题及其答案与特别的一个人遇到的问题。
这个问题不同于关于调试异常的一般建议 https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors因为问题的原因并不总是在调用堆栈上,并且需要具体的建议。
An OutOfMemoryError
是 Java 虚拟机 (JVM) 抛出的异常,因为它需要为(新)对象分配内存,但可供该对象使用的内存不足。 JVM 将首先尝试释放死对象使用的内存,方法是运行垃圾收集器 https://stackoverflow.com/questions/12298725/is-the-garbage-collector-guaranteed-to-run-before-out-of-memory-error.
As an OutOfMemoryError
is a VirtualMachineError
,JVM 被允许把它扔到any time https://stackoverflow.com/questions/8913902/when-exactly-is-the-jvm-throwing-an-outofmemoryerror,虽然它必须首先尝试通过垃圾回收来释放内存 https://stackoverflow.com/questions/12298725/is-the-garbage-collector-guaranteed-to-run-before-out-of-memory-error.
然而,在实践中,它很可能会被抛出new
尝试创建无法为其分配内存的对象的语句。因此,您应该首先检查与异常相关的堆栈跟踪,以获取有关问题原因的线索,就像对待任何其他例外一样 https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors.
- 如果尝试分配数组时抛出异常(例如
int[] values = new int[n]
),原因可能是您正在尝试创建一个过大的数组(n
太大)。您在计算所需数组的大小时犯了错误吗?
- 如果尝试在其他人编写的容器类的方法中分配数组而引发异常,则原因可能是您的代码要求容器存储过多的内容。方法如
ArrayList.reserve(int)
and HashMap(int)
必须分配存储空间以供将来使用。您是否在计算所需容器的尺寸时犯了错误?
- 如果异常是从循环内部引发的,则原因可能是代码循环次数过多。你的循环终止条件正确吗?如果它是一个
for
循环,你要求它循环正确的次数吗?
如果堆栈跟踪没有提供足够的线索,您可以尝试使用堆分析器。这是一个监视程序,使您能够在程序运行时检查对象使用的内存,或检查堆转储程序退出时写入。它可以提供有关内存中存储的对象的大小、数量和类别的信息。
JVM 有一个有限的内存 https://stackoverflow.com/questions/3358328/why-does-the-sun-jvm-have-a-fixed-upper-limit-for-memory-usage-xmx提供给它。您可能会得出这样的结论:您的程序运行正常,但只是需要比可用内存更多的内存来运行。如果你没有明确告诉 JVM 要使用多少内存,大多数实现都会选择一个合理的默认值 https://stackoverflow.com/questions/4667483/how-is-the-default-java-heap-size-determined数量取决于您的计算机拥有的 RAM 数量,但该数量对于您的程序来说可能太小。 JVM 的命令行选项可以控制可用内存量。对于大多数 JVM 实现,这些选项中最重要的是-Xmx https://stackoverflow.com/questions/1030256/java-app-that-uses-a-lot-of-memory-use-xmx and -Xms
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)