解密Java内存溢出之持久代
垃圾回收是Java程序员了解最少的一部分。他们认为Java虚拟机接管了垃圾回收,因此没必要去担心内存的申请,分配等问题。但是随着应用越来越复杂,垃圾回收也越来越复杂,一旦垃圾回收变的复杂,应用的性能将会大打折扣。所以,Java程序员了解垃圾回收的机制并且知道怎样解决“内存溢出”问题会有很大的益处。在Java中,有两个非常普遍的内存溢出问题。一个是堆内存溢出,另一个是持久代内存溢出。
持久代和类加载器
Java对象是java 类的实例。每当创建一个Java对象时,Java虚拟机都会创建该对象的内部引用并且保存在堆中。如果一个类是第一次访问,那么它必须通过Java虚拟机加载进来。类加载是定位,寻找,加载class文件和解析class文件结构的过程。类加载器负责确保加载正确的class文件。Java程序里面每一个class文件需要被同一个类加载加载。类加载器是 java.lang.ClassLoader 类的实例。目前为止,类加载器是在持久代空间里面加载类的。
Java虚拟机也创建了Java类的内部引用保存在持久代。在垃圾回收期间,Java对象和类都当做对象处理并且以同样的方式回收。最初Java对象和类都是保存在堆中。
一个性能优化措施:一旦持久代创建后,就会把classes放入里面。Classes是Java虚拟机的部分实现,我们不应该用我们的数据结构填满Java堆。持久代包含以下类信息:
- 类方法
- 类名称
- 常量池信息
- 对象数组和与类相关的类型数组
- 被Java虚拟机使用的内部对象
- 编译器用于优化的信息
现在我们知道了持久代是什么,接下来看看在这块会是什么原因引起内存问题。
持久代空间
当Java虚拟机需要加载定义的一个新class,但是在持久代中没有足够的空间就会抛出‘Java.Lang.OutOfMemoryError: PermGen Space’异常。默认分配给持久代的大小在server模式下是64MB ,在client模式下是32MB 。这就有两个原因可能会引起持久代内存溢出问题的发生。
第一个原因可能是你应用或者服务器已经有非常多的class在你的持久代中,已经不能容纳所有的class了。
-XX:MaxPermSize=XXXM
如果是因为大量的class导致持久代的空间的不足引起的问题,那么你可以增加持久代的大小通过–XX:MaxPermSize=XXm 参数。这将增加持久代的可用空间来保存class。看起来像这样: -XX:MaxPermSize=256m
-XX:+CMSClassUnloadingEnabled
这个参数表示在使用CMS垃圾回收机制的时候是否启用类卸载功能。默认这个是设置为不启用的,所以你想启用这个功能你需要在Java参数中明确的设置下面的参数:
-XX:+CMSClassUnloadingEnabled
如果你启用了CMSClassUnloadingEnabled ,垃圾回收会清理持久代,移除不再使用的classes。这个参数只有在 UseConcMarkSweepGC 也启用的情况下才有用。参数如下:
-XX:+UseConcMarkSweepGC
-XX:+CMSPermGenSweepingEnabled
这个参数表示是否会清理持久代。默认是不清理的,因此我们需要明确设置这个参数来调试持久代内存溢出问题。这个参数在Java6中被移除了,因此你需要使用 -XX:+CMSClassUnloadingEnabled 如果你是使用Java6或者后面更高的版本。那么解决持久代内存大小问题的参数看起来会是下面这样子:
-XX:MaxPermSize=128m -XX:+UseConcMarkSweepGC XX:+CMSClassUnloadingEnabled
内存泄露
第二个原因可能是内存泄露。那么加载的类怎样变成不用的呢?
在Java中通常class是永久存在的。一旦class被加载,他们就呆在内存中,即使服务器上的应用停掉了。像cglib这样可以动态产生class的类库会使用很多持久代空间,因为它动态的创建很多class。频繁的使用在运行时创建的代理类。当一个类定义可以为多个实例重用时很容易创建新的代理类。
Sping和Hibernate经常会代理某些class。这些代理的class是通过类加载器加载的。产生的类定义如果一直不回收就会导致持久代空间很快就满了。
你需要确定是不是内存泄露引起的持久代空间的问题,同时解决它。增加持久代空间大小将不会有用,这只会延迟它的发生,因为在某个时间点持久代还是会被填满。
如果你正在使用tomcat遇到了内存泄露问题,最新版本的tomcat有能力处理一些内存泄露问题。详细请看:
总结
一旦你遇到了持久代内容溢出问题,你需要找出这个问题是因为加载了大量的class文件还是内存泄露引起的。如果是因为class的数量过多,你可以增加持久代分配的空间大小来解决这个问题。如果是因为内存泄露,你需要引起内存泄露的根源所在并且定位它。一些框架像cglib,Spring,Hibernate会创建大量的动态类,因此对于使用这些框架的应用最好是分配多一点的持久代空间。
原文链接: http://www.javacodegeeks.com/2013/12/decoding-java-lang-outofmemoryerror-permgen-space.html
解密Java内存溢出之持久代的更多相关文章
- Java内存溢出异常(下)
此篇是上一篇文章Java内存溢出异常(上)的续篇,没有看过的同学,可以先看一下上篇.本篇文章将介绍剩余的两个溢出异常:方法区和运行时常量池溢出. 方法区和运行时常量池溢出 这部分为什么会放在一起呢?在 ...
- java内存溢出的解决思路
原文地址:https://www.cnblogs.com/200911/p/3965108.html 内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能 ...
- Java基础学习总结(30)——Java 内存溢出问题总结
Java中OutOfMemoryError(内存溢出)的三种情况及解决办法 相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各 ...
- Java 内存溢出分析
原文地址:Java 内存溢出分析 博客地址:http://www.moonxy.com 一.前言 Java 的 JVM 的内存一般可分为 3 个区:堆(heap).栈(stack)和方法区(metho ...
- 模拟Java内存溢出
本文通过修改虚拟机启动参数,来剖析常见的java内存溢出异常(基于jdk1.8). 修改虚拟机启动参数Java堆溢出虚拟机栈溢出方法区溢出本机直接内存溢出 修改虚拟机启动参数 这里我们使用的是ID ...
- Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结
最近老是遇见服务器内存溢出的问题,故在网上搜了搜,总结了一些java内存溢出的解决方式 java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都 ...
- java内存溢出分析(二)
我们继续java内存溢出分析(一)的分析,点击Details>按钮,显示如下图,我们发现有一个对象数量达到280370216个,再点击其中的List objects 点击后,显示下图 至此,我们 ...
- Java内存溢出详解
转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap ...
- Java内存溢出的详细解决方案
本文介绍了Java内存溢出的详细解决方案.本文总结内存溢出主要有两种情况,而JVM经常调用垃圾回收器解决内存堆不足的问题,但是有时仍会有内存不足的错误.作者分析了JVM内存区域组成及JVM设置虚拟内存 ...
随机推荐
- 条件随机场(Conditional random field)
条件随机场真是把我给折磨坏了啊,本以为一本小小的<统计学习方法>攻坚剩下最后一章,心情还是十分愉悦的,打算一口气把它看完,结果真正啃起来真是无比的艰难啊,每一句对我都好像是天书一般,怎么这 ...
- Nagios 监控系统架设全攻略
Nagios 全名为(Nagios Ain’t Goona Insist on Saintood),最初项目名字是 NetSaint.它是一款免费的开源 IT 基础设施监控系统,其功能强大,灵活性强, ...
- PHP异常处理类(文件上传提示)
知识点: 大部分时候我们的代码总有各种各样的bug,新手程序员(比如我)最经常的工作就是不停的报错和echo变量,一个好的异常处理类可以帮我们更快+更容易理解报错代码的问题,同时,异常处理还可以避免一 ...
- vmware中linux虚拟机使用NAT模式不能连接外网解决
linux虚拟机一直配置的桥接模式,今天改成NAT模式发现不能上外网 环境:VMware12,CentOS 6.8,NAT模式 ①电脑实际ip:192.168.1.100 ②NAT使用虚拟网卡网关: ...
- easyUI tree jQuery
Tree 数据转换 所有节点都包含以下属性: id:节点id,这个很重要到加载远程服务器数据 which is important to load remote data text: 显示的节点文本 ...
- [Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) ](A~E)
A: 题目大意:给你$a,b,c$三条边,可以给任意的边加任意的长度,求最少共加多少长度使得可以构成三角形 题解:排个序,若可以组成,输出$0$,否则输出$c-a-b+1(设a\leqslant b\ ...
- [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解
原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...
- BZOJ2435 [Noi2011]道路修建 【树形Dp 吧。。】
题目 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1条双向道路. 每条道路的修 ...
- echarts移动端字体模糊解决方法
echarts使用canvas画图,在移动端使用rem时候,若viewport的scale被缩放,则字体会发生模糊,本人采用的解决方法是在不同的dpr下使用不同的字体大小,具体代码如下: 获取字体大小 ...
- url为什么要编码及php中的中文字符urlencode基本原理
首先了解以下中文字符在使用urlencode的时候运用的基本原理: urlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%. 此字符串中除了 -_. 之外的所 ...