繁体   English   中英

什么是OutOfMemoryError以及如何调试和修复它

[英]What is an OutOfMemoryError and how do I debug and fix it

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


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

这个问题与调试异常的一般建议不同,因为问题的原因并不总是存在于调用堆栈中,因此有必要提供特定的建议。

OutOfMemoryError是Java虚拟机(JVM)抛出的异常,因为它需要为(新)对象分配内存,但是该对象没有足够的内存。 JVM将首先通过运行垃圾收集器来尝试释放死对象使用的内存。

作为一个OutOfMemoryErrorVirtualMachineError时,JVM允许任何时候把它 ,尽管它必须设法通过垃圾收集首先要释放内存

但是,实际上,它可能会从试图创建无法为其分配内存的对象的new语句中抛出。 因此,您应该像检查其他任何异常一样 ,首先检查与异常相关联的stacktrace,以获取有关问题原因的线索。

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

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

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

要调试OutOfMemoryError ,请使用-XX:+HeapDumpOnOutOfMemoryError选项调用JVM,这将导致在发生OutOfMemoryError时写出堆转储。 然后使用VisualVMjhatfasthat之类的工具查看堆转储。

您还可以随时通过将jmap-dump选项一起使用来手动生成堆转储。

披露:我是fasthat(这是jhat的分支)的维护者。

当应用程序资源用完JVM堆的已分配内存时,将抛出OutOfMemmoryException。 尝试增加JVM堆大小。

当tomcat的内存不足时(即tomcat配置的内存少于运行该应用程序所需的应用程序),就会出现此问题。

因此,要克服此问题,请转到tomcat bin目录创建一个新文件setenv.bat并在该文件中定义PermSize,如下所示:

设置JAVA_OPTS = -Dfile.encoding = UTF-8 -Xms512m -Xmx1024m -XX:PermSize = 512m -XX:MaxPermSize = 1024m

可以根据应用要求将PermSize设置为更大的范围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM