拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 处理“java.lang.OutOfMemoryError: PermGen space”错误

处理“java.lang.OutOfMemoryError: PermGen space”错误

白鹭 - 2022-10-10 2141 0 2

一、概述

PermGen(永久代)是为运行基于JVM 的应用程序分配的一块特殊内存。PermGen 错误是java.lang.OutOfMemoryError系列中的一个,它表示资源(内存)耗尽。

在这个快速教程中,我们将了解导致java.lang.OutOfMemoryError: Permgen space 错误的原因以及如何解决它。

2. Java 内存类型

JVM 使用两种类型的内存:堆栈和堆。堆栈仅用于存储原始类型和对像地址。相反,堆包含对象的值。当我们谈论内存错误时,我们总是指的是堆。实际上,PermGen 是堆内存的一部分,但与JVM 的主内存分离和处理方式不同。要掌握的最重要的概念是,可能有大量可用空间保留在堆中,并且仍然耗尽perm gen 内存。

PermGen 的主要范围是存储Java 应用程序运行时的静态内容:特别是,它包含静态方法、静态变量、对静态对象的引用和类文件。

3. java.lang.OutOfMemoryError: PermGen

简单地说,当为PermGen 分配的空间不再能够存储对象时,就会发生此错误。发生这种情况是因为PermGen 不是动态分配的,并且具有固定的最大容量。64 位版本的JVM 的默认大小为82 Mb,旧的32 位JVM 的默认大小为64 Mb。

PemGen 耗尽的最常见原因之一是与类加载器相关的内存泄漏。实际上,PermGen 包含类文件,类加载器负责加载Java 类。类加载器问题在应用服务器中很常见,其中实例化了多个类加载器以实现各种应用程序的独立部署。

当应用程序被取消部署并且服务器容器保留一个或多个类的引用时会出现问题。如果发生这种情况,类加载器本身就不能被垃圾回收,从而使PermGen 内存与他的类文件饱和。PermGen 崩溃的另一个常见原因是应用程序线程在应用程序取消部署后继续运行,从而维护分配在内存中的多个对象。

4. 处理错误

4.1。调整正确的JVM 参数

对于有限的内存空间,首先要做的是尽可能增加该空间。通过使用特定的标志,可以增加PermGen 空间的默认大小。具有数千个类或大量Java 字符串的大型应用程序通常需要更大的PermGen 空间。通过使用JVM 参数–XX:MaxPermSize可以指定更大的空间来分配给这个内存区域。

由于我们提到了JVM 标志,因此还值得一提的是一个不常用的标志,它会触发此错误。 XnoclassgcJVM 参数,当在JVM 启动时指定时,会从要丢弃的实体列表中显式删除类文件。在应用程序服务器中以及在每个应用程序生命周期中加载和卸载类数千次的现代框架中,这可能会很快耗尽PermGen 空间。

在旧版本的Java 中,类是堆的永久部分,这意味着一旦加载,它们就会保留在内存中。通过指定CMSClassUnloadingEnabled(对于Java 1.5 或CMSPermGenSweepingEnabled对于Java 1.6) JVM 参数,可以启用类的垃圾收集。如果我们碰巧使用的是Java 1.6,UseConcMarkSweepGC也必须设置为true.否则,CMSClassUnloadingEnabled参数将被忽略。

4.2.升级到JVM 8+

修复此类错误的另一种方法是升级到更新版本的Java。从Java 版本8 开始, Permgen 已完全被Metaspace 取代,Metaspace具有自动调整大小的空间和可以清理死类的高级功能。

4.3.堆分析

值得注意的是,如果发生内存泄漏,所提供的任何解决方案都不能满足要求。内存将完成,无论大小。即使元空间也有有限的可用内存量。深度HEAP 分析有时是唯一的解决方案,可以使用VisualGC 或JPROFILER 等工具进行。

五、总结

在这篇简短的文章中,我们看到了PermGen 内存的用途以及与堆内存的主要区别。接下来,我们了解了java.lang.OutOfMemoryError: Permgen 错误的含义以及在哪些特殊情况下会被触发。在上一节中,我们重点介绍了在尝试解决这个特殊问题时可以使用的各种解决方案。


标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *