出现 java.lang.OutOfMemoryError: PermGen space 错误的原因及解决方法
一、原因及解决方法[1]
1、原因:堆内存的永久保存去区内存分配不足(缺省默认为64M),导致内存溢出错误。
2、解决方法:重新分配内存大小,-Xms1024M -Xmx2048M -XX:PermSize=128M -XX:MaxPermSize=256M
3、步骤:[3]
-Xms256m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256M
发布到Tomcat服务器上出现该问题解决方法:[4]
在tomcat 的bin 下catalina.sh 里,位置cygwin=false前,手动添加一行(注意引号要带上,红色的为新添加的)
# OS specific support. $var _must_ be set to either true or false.
JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m"
cygwin=false
二、深入探究[2]
一.Java 程序的运行机制与普通程序,如C或C++ 程序的运行机制有很大的区别。
普通程序运行之前必须首先编译成可执行的二进制码或机器码。机器码是与底层的硬件结构相关的,即使书写源代码的时候没有利用平台特定的扩展语言,如特定的文件访问或图形用户界面,生成的机器码仍然被绑定到一个特定的硬件平台,从而只能运行在那个体系结构上,也就是说,为Sun工作站编译的机器码不能运行在PC机上,为PC机编译的机器码不能运行在苹果机上,以此类推。
与此相反,Java源代码不是为某种特定平台编译的,而是编译成与平台无关的字节码(Byte Code),这种字节码叫做Java Class(Java 类文件)。在任何一种操作系统平台上的字节码都是一样的,因此都可以在任何支持Java 虚拟机(JVM)的计算机上运行。JVM 直接受操作系统控制(而不是Java程序直接受操作系统控制),它负责将字节码转换成在特定平台上能够运行的机器码。正是由于这个原因,Java做到了“write once, run anywhere”(书写一次,到处运行)
运行Java程序时,首先需要由JVM把Java class加载到JVM里面。通常情况下,我们不会去关注JVM的内部工作细节而只是直接拿来使用。然而,作为一个Java开发人员,你经常会遇到与内存相关的性能问题。这个问题最可怕的就是OutOfMemoryError:PermGen space错误。
这个错误通常会在以下三种情况下发生(服务器以Tomcat为例):
(1)应用程序加载了大量的类。
(2)在单一的Tomcat实例下运行多个Web应用程序。
(3)在运行的Tomcat实例中反复“热部署”Web应用程序。
下面我们对该错误进行探究,分析该错误的常见原因,并给出避免这一错误的解决办法。
1.JVM 的内存结构
为了理解这一错误,我们必须了解JVM的内存是如何构造的。
JVM有两个内存区域,一个是堆(heap),另一个是栈(stack)。局部的变量和方法驻留在栈里面,其余的一切都驻留在堆中。
Java的堆又进一步按照区域进行组织,这些区域被称为generation。一个对象在JVM存在的时间越长,它被升迁到老的generation中的几率就越高。年轻的generation要比老的generation更多、更容易地被垃圾回收。同时还存在一些单独的堆空间,被称为永久保存区域(permanent generation),它们不属于Java堆的一部分,用来存放类和类的描述。
类加载器的工作是不断地部署和取消部署Java类。例如,将一个Web应用程序部署到Web服务器或取消部署。在Web服务器上,所有应用程序都有自己的类加载器,部署或取消部署应用程序时,它的类定义和类加载器分别投入到永久保存区域中或者从永久保存区域中删除。
2.OutOfMemoryError: PermGen space
当永久保存区域的空间耗尽时OutOfMemoryError: PermGen space就会发生,这个错误一般是由于内存泄漏导致的。所谓内存泄漏,是指java类和类加载器在被取消部署后不能被垃圾回收。怎么会发生这种情况呢?举个例子:假如我们有一个Student类,这个类是Web应用程序jar包的一部分,同时在Web服务器的lib文件夹中包含了某种日志框架,其中有一个Log类提供register方法调用,从而使得别的类通过注册就可以使用日志功能。如果Student类被注册了,那么Log类就开始拥有了一个对Student对象的引用(reference)。当Student类取消部署时,它仍然是注册Log类的,Log类仍然拥有对Student对象的引用,因此,Student对象永远不会被垃圾回收。此外,由于Student对象拥有一个对它的ClassLoader的引用,所以ClassLoader本身永远也不会被垃圾回收,从而导致由它加载的所有类都不会被回收。
一个更为典型的例子是使用代理对象。Spring和Hibernate常常为某些类生成代理类,这些代理类也是通过类加载器加载的,并且存储在永久保存区域的堆空间,它们永远不会被丢弃,从而会导致永久保存区域的堆空间被填满。
3.如何避免永久保存区域内存不足
3.1 增加PermGen堆的最大尺寸
当遇到java.lang.OutOfMemoryError:PermGen space错误时,我们可以做的第一件事情是增加永久保存区域的最大尺寸,该尺寸的缺省设置是64 M,我们可以将它设置成128 M以上。这个工作不能通过常规的JVM参数 -Xms(设置初始堆大小)和-Xmx(设置最大堆大小)来完成,因为前面已经提到,永久保存区域完全独立于普通的Java堆,这些参数是用来设置普通的Java堆的。不过也有类似参数用于设置永久保存区域的规模:
java -XX:MaxPermSize=128 M
该设置将永久保存区域设置为128 M,这个大小是默认设置的两倍。
对于Tomcat服务器,则需要修改TOMCAT_HOME/bin/catalina.sh
SET JAVA_OPTS=-XX:PermSize=64 M -XX:MaxPermSize=128 M
3.2 避免使用静态字段
确保在编写Java类时,不要使用静态变量作为对其他对象的引用。
3.3使用JDK动态代理,而不是CGLIB代理
一些第三方的框架,如CGLIB会吞食大量的PermGen。因此,当遇到PermGen错误时,应尽快升级cglib到最新版;改用JDK动态代理,也是一个不错的选择。
3.4更新到最新版本Hibernate3.2
此外,新版本的Hibernate不再使用CGLIB作为字节码提供者了,所以及时升级Hibernate,会大大降低出错的机会。
3.5共用的jar文件放到共享目录下
如果在服务器上同时发布了多个应用,那么应该把共用的jar文件放到所有应用都可以访问的目录下。针对Tomcat而言,如果Tomcat下面有多个应用,应尽可能地把lib目录下共用的jar文件放到Tomcat的common\lib或shared\lib下,以避免重复发布,发布速度和运行速度上也会有所提升。
4.结束语
内存不足问题是潜伏较深的问题,且不容易解决。一般情况下,当发生该错误的时候,需要确定为什么某些类不被垃圾回收,只有这样做才能够消除这个错误。
本文摘自中国论文网,原文地址:http://www.xzbu.com/8/view-3801715.htm
Reference:
[1] 维C果糖, 出现 java.lang.OutOfMemoryError: PermGen space 错误的原因及解决方法, https://blog.csdn.net/qq_35246620/article/details/69568205
[2] liuyueyue, Java内存不足之PermGen space错误探究, https://www.cnblogs.com/iliuyuet/p/4315969.html
[3] cuker919, eclipse运行报java.lang.OutOfMemoryError: PermGen space解决方法, https://blog.csdn.net/cuker919/article/details/45246073
[4] 开心萌小小, tomcat启动报错java.lang.OutOfMemoryError:PermGen space解决办法, https://www.cnblogs.com/pistachio123/p/7904581.html
出现 java.lang.OutOfMemoryError: PermGen space 错误的原因及解决方法的更多相关文章
- windows系统bat方式启动tomcat出现java.lang.OutOfmemoryError:PermGen Space 错误
1.问题情景: 在部署项目时,将两个应用部署到同一个tomcat下,通过startup.bat启动服务时,控制台出现出现java.lang.OutOfmemoryError:PermGen Space ...
- [转]Tomcat启动java.lang.OutOfMemoryError: PermGen space错误解决
原文地址:http://outofmemory.cn/java/OutOfMemoryError/outofmemoryerror-permgen-space-in-tomcat-with-eclip ...
- myeclipse tomcat java.lang.OutOfMemoryError: PermGen space错误的解决方法
错误代码: java.lang.OutOfMemoryError: PermGen space 原因分析: myeclipse或tomcat的内容分配的不够用,启动失败 解决方法: 1.找到tomca ...
- java.lang.OutOfMemoryError: PermGen space错误解决方法
1. MyEclipse 中报 PermGen space window--> preferences-->Myclipse-->Servers-->Tomcat- ...
- java.lang.OutOfMemoryError: PermGen space (jvm内存泄漏解决办法)
2.在myeclipse根目录 打开myeclipse.ini 3.在myeclipse中配置内存
- eclipse修改java代码后报错: java.lang.OutOfMemoryError: PermGen space
由于在eclipse中运行项目后,我们又重新修改了某个java类,导致tomcat会重新加载这个项目所有的class.jar,多次加载后由于分配的存储空间有限,就导致了:java.lang.OutOf ...
- 开发部署项目时出现:java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: PermGen space 错误: 原文地址:http://www.cnblogs.com/shihujiang/archive/2012/06 ...
- Tomcat – Java.Lang.OutOfMemoryError: PermGen Space
很多时候,在开发阶段Tomcat重复的重启过程中会遇到java.lang.OutOfMemoryError : PermGen space 错误. 1 2 3 4 java.lang.OutOfMem ...
- java.lang.OutOfMemoryError:PermGen space tomcat7 内存溢出
Tomcat 解决 在启动项目的时候,会报java.lang.OutOfMemoryError:PermGen space错误. 在tomcat/bin/catalina.sh windows li ...
随机推荐
- Vue学习之全局和私有组件小结(七)
一.组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用相应的组件即可. 二.组件和模块: 1.模块化:是从代码逻 ...
- Windows 10 下 GCC / LLVM 的安装和使用
win10下gcc的安装和makehttps://www.jianshu.com/p/46824c62dfed 方案1:直接官方下载安装minGw或Cygwininstall download: ht ...
- JVM 入门指南
一.什么是JVM? JVM: JVM是Java Virtual Machine的缩写,中文翻译为Java虚拟机.JVM 可以看作一台抽象的计算机,如同真实的计算机一样,它有自己的指令集和各种运行时区域 ...
- win黑窗口命令
rd 删除 文件夹, 语法: rd [/S] [/Q] [drive:]path 参数: drive 盘符 path 文件路径 /S 递归删除文件夹( 删除前, 要确认是否进行删除) /Q 关闭 ...
- zabbix--监控MySQL性能
Zabbix 自带模板监控 MySQL 性能 通过自带的 Template DB MySQL 模板监控 MySQL 性能 具体步骤: 1)创建脚本存放目录并编辑脚本 # mkdir /etc/zabb ...
- LVS负载均衡部署
一.lvs-nat模式 1.1.环境介绍 本实验用三台虚拟机完成,一台虚拟机模拟lvs调度器,两块网卡,一块模拟公网一块模拟私网,公网地址192.168.0.201/24,私网地址192.168.4. ...
- async和await执行顺序
关于执行顺序和线程ID,写了一个小程序来检测学习: using System; using System.Net; using System.Threading; using System.Threa ...
- The 2016 ACM-ICPC Asia China-Final D. Ice Cream Tower 二分 + 贪心
题目大意: 对于给出的n个冰激凌球的大小,满足下面的球的大小是上一个的至少2倍,对于给出的k(由k的冰激凌球才能算作一个冰激凌塔),问n个冰激凌球可以最多堆出多少个高度为k的冰激凌塔 题目分析: 对于 ...
- PAT 乙级 1011.A+B 和 C C++/Java
题目来源 给定区间 [−] 内的 3 个整数 A.B 和 C,请判断 A+B 是否大于 C. 输入格式: 输入第 1 行给出正整数 T (≤),是测试用例的个数.随后给出 T 组测试用例,每组占一行, ...
- Codeforces H. Prime Gift(折半枚举二分)
题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...