迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 中的 java.lang.OutOfMemoryError 介绍

作者:迹忆客 最近更新:2023/02/08 浏览次数:

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 中的 OutOfMemoryErrorjava.lang.VirtualMachineError 的子类,JVM 在堆内存不足时抛出 java.lang.OutOfMemoryError。 Java 中的 OutOfMemoryError 可以在堆中随时出现,主要是当我们尝试创建对象并且堆上没有足够的空间来分配该对象时。 不过,OutOfMemoryError 的 Javadoc 对此并没有提供很多信息。

Java 中 OutOfMemoryError 的类型

我在 Java 中主要看到了两种类型的 OutOfMemoryError:

  1. java.lang.OutOfMemoryError: Java 堆空间
  2. 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

  1. 在 Java 中解决 OutOfMemoryError 的一个简单方法是使用 JVM 选项“**-Xmx512M** ”增加最大堆大小,这将立即解决我们的 OutOfMemoryError。 当我在构建项目时在 Eclipse、Maven 或 ANT 中遇到 OutOfMemoryError 时,这是我的首选解决方案,因为根据项目的大小,很容易耗尽内存。

这是增加 JVM 最大堆大小的示例,如果我们在 Java 应用程序中设置堆大小,最好将 -Xmx-Xms 的比例保持在 1:1 或 1:1.5

export JVM_ARGS="-Xms1024m -Xmx1024m"
  1. 在 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 应用程序生成的线程。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 Java 中获取文件大小

发布时间:2023/05/01 浏览次数:139 分类:Java

Java 提供了不同的方法来获取文件的字节大小。 本教程演示了在 Java 中获取文件大小的不同方法。使用 Java IO 的文件类获取文件大小 Java IO 包的 File 类提供了以字节为单位获取文件大小的功能。

Java 中的文件分隔符

发布时间:2023/05/01 浏览次数:108 分类:Java

本篇文章介绍了 Java 中的文件分隔符。Java 中的文件分隔符 文件分隔符是用来分隔目录的字符; 例如,Unix 使用 /,Windows 使用 \ 作为文件分隔符。

Java 中的文件过滤器

发布时间:2023/05/01 浏览次数:193 分类:Java

本篇文章介绍如何在 Java 中使用 FileFilter。FileFilter 用于过滤具有特定扩展名的文件。 Java内置包IO和Apache Commons IO为FileFilter提供了类和接口来进行文件过滤操作。

Java 获取 ISO 8601 格式的当前时间戳

发布时间:2023/05/01 浏览次数:132 分类:Java

本篇文章介绍了 ISO 8601 日期格式、其重要性及其在 Java 中的使用。 它还列出了一些优点来强调为什么应该使用 ISO 格式来表示日期。

在 Java 中获取数组的子集

发布时间:2023/05/01 浏览次数:142 分类:Java

本篇文章介绍了几种在 Java 中获取数组子集的方法。使用 Arrays.copyOf() 方法获取数组的子集 使用 Arrays.copyOfRange() 方法获取数组的子集

用 Java 填充二维数组

发布时间:2023/05/01 浏览次数:110 分类:Java

二维数组是基于表结构的,即行和列,填充二维数组不能通过简单的添加到数组操作来完成。 本篇文章介绍如何在 Java 中填充二维数组。

Java 中的自然排序

发布时间:2023/05/01 浏览次数:132 分类:Java

Java 中最常用的顺序是自然顺序。 本文将展示如何使用 naturalOrder() 函数对数组进行排序。

计算 Java 数组中的重复元素

发布时间:2023/05/01 浏览次数:202 分类:Java

本篇文章介绍Java计算数组中重复元素的方法。计算 Java 数组中的重复元素。我们可以创建一个程序来计算数组中的重复元素。 该数组可以是未排序的,也可以是已排序的。

Java 中 List 和 Arraylist 的区别

发布时间:2023/05/01 浏览次数:90 分类:Java

表示为单个单元的一组单个对象称为集合。 在 Java 中,Collection 是一个具有多个已定义接口和类的框架,用于将一组对象表示为一个单元。 它允许我们操纵

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便