我的Java程序抛出OutOfMemoryError
。如何调试并修复此问题?
Java的许多新手都在努力应对OutOfMemoryError
。这是尝试创建一个规范问题,该问题将回答有关OutOfMemoryError
的最常见问题。我正在创建这个新问题,而不是调整之前关于OutOfMemoryError
的众多问题之一,因为这些问题及其答案与一个人的特定问题紧密相关。
答案 0 :(得分:9)
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要使用多少内存,大多数实现将根据您的计算机具有的RAM量选择sensible default数量,但该数量对于您的程序来说可能太小。 JVM的命令行选项可以控制可用内存量。对于大多数JVM实现,其中最重要的选项是-Xmx
和-Xms
。
答案 1 :(得分:6)
要调试OutOfMemoryError
,请使用-XX:+HeapDumpOnOutOfMemoryError
选项调用JVM,这将导致在OutOfMemoryError
发生时写出堆转储。然后使用VisualVM,jhat或fasthat等工具查看堆转储。
您也可以使用-dump
选项jmap随时手动生成堆转储。
披露:我是fasthat的维护者,这是一个jhat的分支。
答案 2 :(得分:0)
当应用程序资源耗尽JVM堆的已分配内存时,将抛出OutOfMemmoryException。尝试增加JVM堆大小。
答案 3 :(得分:0)
当tomcat内存不足时会出现此问题,即tomcat配置的内存少于运行应用程序所需的应用程序。
要解决此问题,请转到 tomcat bin目录并创建新文件setenv.bat ,并在该文件中定义PermSize,如下所示:
设置JAVA_OPTS = -Dfile.encoding = UTF-8 -Xms512m -Xmx1024m -XX:PermSize = 512m -XX:MaxPermSize = 1024m
根据应用要求,可以将PermSize设置为更高的范围。