Java 中的 java.lang.OutOfMemoryError 介绍
Java 开发中的每个人时不时都会遇到 java.lang.OutOfMemoryError
,Java 中的 OutOfMemoryError
是一个问题,在大多数情况下更多是由于系统的限制(内存)而不是由于编程错误,尽管在某些情况下我们可能会出现内存泄漏 这导致 OutOfMemoryError
。 我发现,尽管 java.lang.OutOfMemoryError
是其原因的常见基础知识,而且初级开发人员在很大程度上不知道解决方案。我们需要具有处理生产系统、处理大量用户会话的真实经验,以解决和解决内存不足等性能问题。
在本文中,我们将探讨什么是 java.lang.OutOfMemoryError
; 为什么 OutOfMemoryError 出现在 Java 应用程序中,不同类型的 OutOfMemoryError 以及如何修复 Java 中的 OutOfMemoryError。
本文纯粹是为了提供 java.lang.OutMemoryError
的基础知识,不会详细讨论分析。
Java 中的 java.lang.OutOfMemoryError 是什么
Java 中的 OutOfMemoryError 是 java.lang.VirtualMachineError
的子类,JVM 在堆内存不足时抛出 java.lang.OutOfMemoryError
。 Java 中的 OutOfMemoryError 可以在堆中随时出现,主要是当我们尝试创建对象并且堆上没有足够的空间来分配该对象时。 不过,OutOfMemoryError 的 Javadoc 对此并没有提供很多信息。
Java 中 OutOfMemoryError 的类型
我在 Java 中主要看到了两种类型的 OutOfMemoryError:
-
java.lang.OutOfMemoryError
: Java 堆空间 -
java.lang.OutOfMemoryError
: PermGen 空间
尽管它们都是因为 JVM 内存不足而发生的,但它们彼此完全不同,并且它们的解决方案彼此独立。
“java.lang.OutOfMemoryError: Java heap space”和“java.lang.OutOfMemoryError: PermGen space”的区别
如果我们熟悉堆上的不同世代和垃圾收集在 Java 中的工作方式,并了解堆空间的新代、旧代和永久代,那么我们很容易在 Java 中找出这个 OutOfMemoryError。 永久代堆用于存放String pool和JVM所需的各种与Class、method等java原语相关的Metadata。
由于 Perm Space 的大多数 JVM 默认大小约为“64MB”,如果我们的项目中有太多类或大量字符串,很容易耗尽内存。
要记住的重要一点是它不依赖于 –Xmx 值,因此无论我们的总堆大小有多大,都可以在 perm 空间中运行 OutOfMemory。 好处是我们可以根据项目需要使用 JVM 选项“**-XX: PermSize** ”和“**-XX: MaxPermSize** ”指定永久代的大小。
需要记住的一件小事是,在指定堆中的永久空间大小时,=
用于分隔参数和值,而在 java 中设置最大堆大小时,则不需要 =
,如下例所示。
export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"
“java.lang.OutOfMemoryError: PermGen”的另一个原因是通过类加载器的内存泄漏,它经常出现在 WebServer 和应用程序服务器中,如 tomcat、WebSphere、glassfish 或 WebLogic。
在应用程序服务器中,不同的类加载器用于加载不同的 Web 应用程序,以便我们可以部署和取消部署一个应用程序而不会影响同一服务器上的其他应用程序,但如果容器以某种方式保留对应用程序类加载器加载的任何类的引用,则在取消部署时 那么该类和所有其他相关类将不会被垃圾收集,并且如果我们多次部署和取消部署您的应用程序,它们可以快速填充 PermGen 空间。
“java.lang.OutOfMemoryError: PermGen”在我们上一个项目的tomcat中出现过很多次,但是这个问题的解决真的很棘手,因为首先你需要知道是哪个类导致了内存泄漏,然后你需要修复它 . PermGen 空间中 OutOfMemoryError 的另一个原因是,当我们取消部署应用程序时,应用程序启动的任何线程都没有退出。
这些只是臭名昭著的类加载器泄漏的一些示例,任何编写用于加载和卸载类的代码的人都必须非常小心地避免这种情况。 我们还可以使用 visualgc 来监视 PermGen 空间,此工具将显示 PermGen 空间的图表,我们可以看到永久空间如何以及何时增加。 我建议在得出任何结论之前使用此工具。
我们发现“java.lang.OutOfMemoryError: PermGen”的另一个未知但有趣的原因是 JVM 选项“**-Xnoclassgc** ”的引入。
这个选项有时用于避免在没有进一步的实时引用时加载和卸载类,只是为了避免由于频繁加载和卸载而导致的性能损失,但是使用这个选项是 J2EE 环境可能非常危险,因为许多框架如 Struts , spring 等使用反射来创建类,如果没有清理早期的引用,频繁的部署和取消部署很容易耗尽 PermGen 中的空间。 此实例还指出,有时错误的 JVM 参数或配置会导致 Java 中出现 OutOfMemoryError
。
所以结论是避免在 J2EE 环境中使用“**-Xnoclassgc** ”,尤其是在 AppServer 中。
Tomcat解决PermGen空间OutOfMemoryError
从 tomcat > 6.0 开始,tomcat 提供了内存泄漏检测功能,可以从 Web 应用程序的角度检测许多常见的内存泄漏,例如 ThreadLocal 内存泄漏、JDBC 驱动程序注册、RMI 目标、LogFactory 和由 Web 应用程序生成的线程。
如何解决java.lang.OutOfMemoryError: Java heap space
-
在 Java 中解决
OutOfMemoryError
的一个简单方法是使用 JVM 选项“**-Xmx512M** ”增加最大堆大小,这将立即解决我们的 OutOfMemoryError。 当我在构建项目时在 Eclipse、Maven 或 ANT 中遇到 OutOfMemoryError 时,这是我的首选解决方案,因为根据项目的大小,很容易耗尽内存。
这是增加 JVM 最大堆大小的示例,如果我们在 Java 应用程序中设置堆大小,最好将 -Xmx 与 -Xms 的比例保持在 1:1 或 1:1.5
export JVM_ARGS="-Xms1024m -Xmx1024m"
-
在 Java 中解决 OutOfMemoryError 的第二种方法相当困难,当你没有太多内存时就会出现,即使在增加最大堆大小之后你仍然会遇到
java.lang.OutOfMemoryError
,在这种情况下,你可能想要分析 我们的应用程序并查找任何内存泄漏。
我们还可以使用 Eclipse Memory Analyzer 来检查我们的堆转储,或者我们可以使用任何分析器,如 Netbeans 或 JProbe。 这是一个艰难的解决方案,需要一些时间来分析和查找内存泄漏。
如何解决java.lang.OutOfMemoryError: PermGen space
正如上一段中所解释的,Java 中的这个 OutOfMemory 错误是在堆的永久代被填满时出现的。 要在 Java 中修复此 OutOfMemoryError,我们需要使用 JVM 选项“**-XX:MaxPermSize** ”来增加 Perm 空间的堆大小。
我们还可以使用“**-XX: PermSize** ”指定 Perm 空间的初始大小,并通过保留初始和最大 Perm 空间可以防止在重新调整 Perm 空间大小时可能发生的某些完全垃圾收集。 以下是如何在 Java 中指定初始和最大 Perm 大小:
export JVM_ARGS="-XX:PermSize=64M -XX:MaxPermSize=256m"
有时 Java 中的 java.lang.OutOfMemoryError
变得棘手,在这些情况下,分析仍然是最终的解决方案。虽然我们可以自由地增加 Java 中的堆大小,但建议在编码时遵循内存管理实践并将任何未使用的引用设置为 null。
以上就是我关于 Java 中的 OutOfMemoryError 的全部内容,我将尝试在其他文章中写更多关于在 Java 中查找内存泄漏和使用分析器的内容。
重要说明
:从 Tomcat > 6.0 开始,tomcat 提供了内存泄漏检测功能,可以检测 Java 应用程序上的许多常见内存泄漏,例如 ThreadLocal 内存泄漏、JDBC 驱动程序注册、RMI 目标、LogFactory 和 Web 应用程序生成的线程。
相关文章
Do you understand JavaScript closures?
发布时间:2025/02/21 浏览次数:108 分类:JavaScript
-
The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.
Do you know about the hidden traps in variables in JavaScript?
发布时间:2025/02/21 浏览次数:178 分类:JavaScript
-
Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av
How much do you know about the Prototype Chain?
发布时间:2025/02/21 浏览次数:150 分类:JavaScript
-
The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start
如何在 JavaScript 中合并两个数组而不出现重复的情况
发布时间:2024/03/23 浏览次数:86 分类:JavaScript
-
本教程介绍了如何在 JavaScript 中合并两个数组,以及如何删除任何重复的数组。