我的Java程序抛出了OutOfMemoryError。如何调试和解决此问题?

Java的许多新手努力应对OutOfMemoryError。这是尝试创建一个规范问题,以回答有关OutOfMemoryError的最常见问题。我正在创建这个新问题,而不是改编以前有关OutOfMemoryError的众多问题之一,因为这些问题及其答案与人所遇到的特定问题紧密相关。

此问题与general advice on debugging exceptions不同,因为问题的原因并不总是存在于调用堆栈中,因此需要特定的建议。

最佳答案

OutOfMemoryError是Java虚拟机(JVM)抛出的异常,因为它需要为(新)对象分配内存,但是该对象没有足够的内存。 JVM将首先通过running the garbage collector尝试释放死对象使用的内存。

因为OutOfMemoryErrorVirtualMachineError,所以允许JVM允许throw it at any time,尽管它必须是try to release memory through garbage collection first

但是,实际上,它很可能从试图创建无法为其分配内存的对象的new语句中抛出。因此,您应该首先检查与异常相关联的stacktrace,以获取有关问题原因as you would for any other exception的线索。

  • 如果尝试分配数组而引发异常(例如int[] values = new int[n]),则可能是因为您试图创建一个过大的数组(n太大)。您在计算所需数组大小时是否犯了一个错误?
  • 如果尝试在其他人编写的容器类的方法中分配数组而引发异常,则原因可能是您的代码要求容器存储过多的东西。诸如ArrayList.reserve(int)HashMap(int)之类的方法必须分配存储以供将来使用。您在计算所需的容器尺寸时是否犯了一个错误?
  • 如果从循环内部引发异常,则原因可能是代码循环了太多次。循环终止条件正确吗?如果它是for循环,是否要求它循环正确的次数?

  • 如果stacktrace没有提供足够的线索,则可以尝试使用堆分析器。这是一个监视程序,使您可以在程序运行时检查用于对象的内存,或检查程序退出时写入的堆转储。它可以提供有关存储在内存中的对象的大小,数量和类别的信息。

    JVM有一个finite amount of memory可供使用。您可能会得出结论,您的程序行为正确,但是只需要运行更多的内存即可使用。如果您没有明确告诉JVM使用多少内存,大多数实现将基于计算机拥有的RAM量来选择sensible default量,但是该量对于您的程序而言可能太小了。 JVM的命令行选项可以控制提供多少内存。对于大多数JVM实现,这些选项中最重要的是 -Xmx -Xms

    关于java - 什么是OutOfMemoryError以及如何调试和修复它,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24510188/

    10-13 04:35