内存的永久保存区内存溢出解决

本文探讨了Java应用程序中PermGenSpace与HeapSpace内存溢出的问题,包括问题产生的原因、常见场景及如何通过调整JVM参数来解决这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在开发的过程中遇到一个错误:java.lang.OutOfMemoryError: PermGen space。PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m 2、在tomcat中redeploy时出现outofmemory的错误. 可以有以下几个方面的原因: 

 1,使用了proxool,因为proxool内部包含了一个老版本的cglib. 
 2, log4j,最好不用,只用common-logging 
 3, 老版本的cglib,快点更新到最新版。
 4,更新到最新的hibernate3.2 3、

 这里以tomcat环境为例,其它WEB服务器如jboss,weblogic等是同一个道理。
 一、java.lang.OutOfMemoryError: PermGen space PermGen space的全称是Permanent Generation space,是指内存的永久保存区域, 这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中, 它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对 PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误, 这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
 解决方法: 手动设置MaxPermSize大小修改TOMCAT_HOME/bin/catalina.sh 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m 
 建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。
 二、java.lang.OutOfMemoryError: Java heap space Heap size 设置 JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 
 解决方法:手动设置Heap size 修改TOMCAT_HOME/bin/catalina.sh 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m" 
 三、实例,以下给出1G内存环境下java jvm 的参数设置参考: JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true " 
 


### 内存溢出 (Heap Memory Overflow) 内存溢出通常是因为应用程序尝试分配的内存超出了JVM的最大容量。这种情况下,JVM会抛出 `java.lang.OutOfMemoryError` 错误。 #### 原因 - **大对象分配失败**:一次性创建过大的对象或集合结构,导致剩余空间不足[^2]。 - **内存泄漏**:某些对象不再被使用但仍保持引用,阻止垃圾回收器清理这些对象[^4]。 #### 解决方案 - 提高内存上限通过调整 `-Xmx` 参数来增大最大大小。 - 使用性能监控工具定位并修复内存泄漏问题,例如 VisualVM 或 JProfiler。 ```bash java -Xms512m -Xmx2g MyApplication ``` --- ### 栈内存溢出 (Stack Overflow) 栈内存溢出通常是由于线程调用层次太深或者存在无限递归造成的。 #### 原因 - **死循环递归**:函数反复自我调用直到栈帧耗尽所有可用栈空间[^1]。 - **局部变量过多**:单个方法中定义了大量局部变量也可能引发此问题。 #### 解决方案 - 减少递归深度改写算法逻辑为迭代形式。 - 调整线程栈大小参数 `-Xss` 来增加每个线程默认拥有的栈尺寸。 ```bash java -Xss1m RecursiveExample ``` --- ### 方法(元空间)内存溢出 (Metaspace/Metaspace Overflow) 方法内存主要用于存储类的相关数据,在 JDK 8 及之后称为元空间(Metaspace),而在更早版本则被称为永久代(PermGen Space)。 #### 原因 - **加载太多 Class 文件**:动态代理、反射操作频繁生成新类实例可能导致该域膨胀迅速。 - **未释放无用 Classes**:即使应用卸载了一些模块但对应 classes 并未真正销毁仍占据着位置[^5]。 #### 解决方案 - 对于旧版 JDK (<8), 设置适当 Permanent Generation 大小 via `-XX:MaxPermSize`. - 新版 JDK 中, 扩展 MetaSpace 上限至合理范围 by modifying `-XX:MaxMetaSpaceSize`. ```bash # For older versions of Java before JDK 8 java -XX:MaxPermSize=256m MyClassLoader # For newer versions starting from JDK 8 onwards java -XX:MaxMetaspaceSize=512m DynamicClassLoaderApp ``` --- ### 总结注意事项 除了上述三种主要类型的 OOM 异常外还有其他情况比如直接缓冲池等情况也需要留意处理方式各有侧重需具体分析实际应用场景做出相应优化措施[^3].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值