本文由 ImportNew - Peter
Pan
 翻译自 javacodegeeks。如需转载本文,请先参见文章末尾处的转载要求。

ImportNew注:如果你也对Java技术翻译分享感兴趣,欢迎加入我们的 Java开发 小组。参与方式请查看小组简介。

垃圾回收是Java开发人员理解得最不彻底的地方之一。他们觉得既然JVM负责垃圾回收,那么便不必担心内存的分配跟回收等问题。但是当应用变得复杂的时候,垃圾回收同样变得复杂起来,而且一旦垃圾回收变得复杂,程序的性能就会受到影响。所以,这篇文章将会帮助Java开发人员更好地理解垃圾回收机制是怎样工作的,以及如何修复Java中的“Out of Memory”问题。有两个十分普遍的导致“Out of Memory”问题的因素。第一个是堆大小,第二个就是PermGen Space。

永久代和类加载器

Java对象是Java类的实例。每一次创建一个新的Java对象,JVM就会创建一个该对象的内部标识并把该对象存储在堆中。如果是首次访问该类,JVM就必须加载它。类加载是定位相关类文件、在硬盘上找到该文件、加载该文件并解析文件结构的一系列过程。确保类的正确加载是类加载器(ClassLoader)的责任。一个Java程序中的每一个类都必须被相同的类加载器加载。类加载器是java.lang.ClassLoader类的实例。类加载器把Java类暂时加载到Perm Space中。

JVM也创建了Java类的内部标识并把java类存储在永久代中。在垃圾回收期间,对象跟类都被看作对象且用相同的方式进行垃圾回收。最初,类和对象都被存储在堆空间。

作为优化性能,会创建永久代并将被放在永久代中。类是我们的JVM实现的一部分,并且我们不应该用数据结构填满Java堆。永久代内存分配在堆之外,包含以下类的信息:

  • 类的方法
  • 类的名字
  • 常量池信息
  • 跟类有关的对象数组和类型数组
  • JVM使用的内部对象
  • 编译器优化的使用信息

既然现在我们已经理解了永久代是什么,那么就让我们看一看是什么引发了内存问题。

PermGen Space

当JVM需要加载一个新类的定义的却发现在PermGen没有足够的空间时,”java.lang.OutOfMemoryError: PermGen Space”错误便发生了。默认分配的永久代内存空间(PermGen Space),服务器模式是64M,客户端模式是32M。有两个可能原因导致永久代内存空间问题。

第一个原因可能是你的应用程序或服务器拥有太多的类,而已有永久代内存空间不足以容纳所有的类。

-XX:MaxPermSize=XXXM

如果出现OOM,这是因为类太多而引起的永久代内存空间不足,那么你可以通过增加 +XX:MaxPermGenSize=XXXM 大小的方式来增加永久代的内存空间。这样做会加大存储类的空间变量的大小,并且 +XX:MaxPermGenSize 参数应该设置为256M。

-XX:+CMSClassUnloadingEnabled

这个参数显示在使用CMS GC时,未加载类是否可用。该参数默认值为false,由此,你需要在java选项中显示设置下面选项:

1
-XX:+CMSClassUnloadingEnabled

如果你启用 CMSClassUnloadingEnabled ,JVM进行GC时便会清除永久代,并且删除不再使用的类。这个选项只会在 UseConcMarkSweepGC 可用时才起作用。通过以下选项使
UseConcMarkSweepGC 可用:

1
-XX:+
UseConcMarkSweepGC

-XX:+CMSPermGenSweepingEnabled

这个参数显示清除永久代是否可用。默认情况下这个参数是不可用的,所以要协调永久代问题,就必须显示设置这个参数。这个参数在Java 6里面被删除,所以如果你在使用Java 6或以上版本,你将不得不使用 -XX:+CMSClassUnloadingEnabled 选项。所以,为了解决永久代空间的内存问题,被添加的选项看起来如下:

1
-XX:MaxPermSize=128M
–XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

内存泄漏

第二个原因可能是内存泄露。被加载的类定义如何变成没有被使用?

正常情况下,在Java中类是永久存在的。所以一旦类被加载,他们将一直停留在内存中,即便其所在应用服务器端已经停止运行。像cglib这样的动态类产生库,在他们动态创建了大量类之后,会使用大量永久代内存空间。在运行时创建的代理类被广泛地使用。当单个类定义被用于产生多个实例时,创建新的代理类将会很容易。

Spring和Hibernate经常产生某个类的代理,这些代理类被类加载器加载。产生的类定义从不被清理,导致永久性堆空间迅速填满。

为了解决永久代内存空间问题,你需要识别出泄露的原因并修补它。增大永久代内容空间不会有益于解决却只会延缓这类问题,因为在某种意义上,永久代内存空间终将被填满。

如果你正在使用Tomcat且经常遇到内存溢出问题,最新版本的Tomcat已经有足够的容量来解决某些内存溢出问题。

总结

一旦你遇到永久代内存空间问题,你需要找出这个问题是否是由于你的应用程序加载了大量的类或出现了内存泄露。如果是由于类太多,精确地协调分配永久代内存空间能够解决。如果是由于内存泄露,你需要找到泄露的根本原因并标记出来。像cglib、Spring、Hibernate这样的框架会动态生成大量的类,所以在使用这些框架时分配更多的永久代内存空间是更好的选择。

原文链接: javacodegeeks 翻译: ImportNew.comPeter
Pan

译文链接: http://www.importnew.com/8133.html

解码OutOfMemoryError:PermGen Space的更多相关文章

  1. Eclipse中启动tomcat报错java.lang.OutOfMemoryError: PermGen space的解决方法

    有的项目引用了太多的jar包,或者反射生成了太多的类,异或有太多的常量池,就有可能会报java.lang.OutOfMemoryError: PermGen space的错误, 我们知道可以通过jvm ...

  2. java.lang.OutOfMemoryError: PermGen space及其解决方法

    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决 ...

  3. [转]Tomcat启动java.lang.OutOfMemoryError: PermGen space错误解决

    原文地址:http://outofmemory.cn/java/OutOfMemoryError/outofmemoryerror-permgen-space-in-tomcat-with-eclip ...

  4. 【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便

    Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalin ...

  5. tomcat 运行程序很慢 运行一段时间就报错: java.lang.OutOfMemoryError: PermGen space

    java.lang.OutOfMemoryError: PermGen space 全称是Permanent Generation space,是指内存的永久保存区域. 由于这块内存主要是被JVM存放 ...

  6. [转]java.lang.OutOfMemoryError: PermGen space及其解决方法

    原文地址:http://peak.iteye.com/blog/52606 这个问题是我的工程中加入了Birt报表在Linux环境下运行出现的问题,从网上搜索了一下看到这文章发现并不是由于Birt的原 ...

  7. Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)

    Tomcat启动时报如下错误:     java.lang.OutOfMemoryError: PermGen space 解决办法:     配置相关内存大小.其中按照启动tomcat的不同方式,分 ...

  8. java.lang.OutOfMemoryError: PermGen space

    Exception in thread ""http-bio-8080"-exec-1" java.lang.OutOfMemoryError: PermGen ...

  9. Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决

    解决方案 在 catalina.bat 里的 蓝色代码前加入: 红色代码 rem ----- Execute The Requested Command ----------------------- ...

  10. java.lang.OutOfMemoryError: PermGen space及其解决方法(转载)

    java.lang.OutOfMemoryError: PermGen space及其解决方法 分类: java2007-09-11 12:34 162242人阅读 评论(51) 收藏 举报 gene ...

随机推荐

  1. 性能、成本与 POSIX 兼容性比较: JuiceFS vs EFS vs FSx for Lustre

    JuiceFS 是一款为云环境设计的分布式高性能文件系统.Amazon EFS 易于使用且可伸缩,适用于多种应用.Amazon FSx for Lustre 则是面向处理快速和大规模数据工作负载的高性 ...

  2. Spark Dataframe 转 Json

    import org.apache.spark.sql.DataFrame import org.apache.spark.sql.functions._ import org.apache.spar ...

  3. Figma 学习笔记 – Align 对齐

    Figma 有几个常用的对齐方法 从左到右 1. 左对齐 Alt + A 2.左右居中对齐 Alt + H 3.右对齐 Alt + D 4.上对齐 Alt + W 5.上下居中对齐 Alt + V 6 ...

  4. servlet一些笔记、详解

    一.什么是servlet? 处理请求和发送响应的过程是由一种叫做Servlet的程序来完成的,并且Servlet是为了解决实现动态页面而衍生的东西.理解这个的前提是了解一些http协议的东西,并且知道 ...

  5. 单Master节点的k8s集群部署-完整版

    K8S 安装步骤 一.准备工作 1.准备三台主机(一台Master节点,两台Node节点)如下: 角色 IP 内存 核心 磁盘 Master 192.168.116.131 4G 4个 55G Nod ...

  6. gaussian噪声

    高斯噪声 高斯噪声(Gaussian noise)是一种具有正态分布(也称作高斯分布)概率密度函数的噪声.换句话说,高斯噪声的值遵循高斯分布或者它在各个频率分量上的能量具有高斯分布.它被极其普遍地应用 ...

  7. 28. 找出字符串中第一个匹配项的下标 Golang实现

    题目描述: 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始).如果 needle 不是 hay ...

  8. 10月《中国数据库行业分析报告》已发布,深度剖析甲骨文大会Oracle技术新趋势

    为了帮助大家及时了解中国数据库行业发展现状.梳理当前数据库市场环境和产品生态等情况,从2022年4月起,墨天轮社区行业分析研究团队出品将持续每月为大家推出最新<中国数据库行业分析报告>,持 ...

  9. Oracle ASM磁盘组配置、日常运维、故障处理等操作资料汇总

    ASM(自动存储管理)在数据库中是非常重要的组成部分,它可以为磁盘提供统一的存储管理.提高磁盘访问的性能和可用性.简化管理复杂度,从而为数据库的运行提供更好的支持. 这里就为大家整理了墨天轮数据社区上 ...

  10. is特性

    is是特性在动态路由的时候使用 ,在挂载点 component 使用,用来判断哪个组件显示 :