- 1、本文档共9页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Java内存溢出之PermGen OOM
Java内存溢出之PermGen OOM深入分析
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????朱兴 2008-3-28/zhuxing/articles/1247621.html
现在,有关讨论JAVA内存泄漏的文章很多。java的内存泄漏基本上按照内存区域的划分可以分为:
堆(heap)内存泄漏:大家都比较熟悉
栈(stack)内存泄漏:当前线程运行期间维护的中间变量等信息过多,例如常见的死循环引起stack over flow
方法区(permanent heap)内存泄漏:分析其原因的文章较少,本文的着重点。
网上关于讨论PermGen OOM的资料很多,但是深入分析PermGen区域内存溢出原因的资料很少。本篇文章尝试全面分析一下PermGen OOM的原因,其中涉及到了Java虚拟机运行时数据区、类型装载、类型卸载等,测试代码涉及到了JMX协议。【相关知识】
Java类加载相关的知识,《Java类加载原理简析》中结合JDK的代码实现对Java类加载的原理做了比较深入的分析.
Java类型卸载相关的知识,《Java虚拟机类型卸载和类型更新解析 》中对结合Java虚拟机规范对虚拟机类型卸载和类型更新做了较为深入的分析,网址链接/modules/newbb/forumtopic14058_8610_40.htm。
有关JMX协议可以参加sun公司发布的技术规范,对JMX协议做一定的了解对理解Java性能监控和调优功能的实现原理有很大帮助。
虚拟机运行时数据区介绍
本部分将对Java虚拟机运行时数据区做一个简单的介绍,着重说明PermGen区域(永久存储区)存放的内容,并对运行时数据区的访问方式做一个归纳说明,为后面深入分析类型卸载和PermGen OOM做铺垫。为了更具有通用性,本部分将更多关注虚拟机协议本身,可能和具体的虚拟机实现有少许的出入。
运行时数据区分类
Java虚拟机的运行时数据区一般分类如下(不一定是物理划分):
堆:主要存放对象实例,线程共享
栈:主要存储特定线程的方法调用状态,线程独占
本地方法栈:存储本地方法的调用状态,线程独占
PC寄存器:学过操作系统课程的都知道,线程独占
方法区:主要存储了类型信息,线程共享
方法区可以简单的等价为所谓的PermGen区域(永久存储区),在很多虚拟机相关的文档中,也将其称之为永久堆(permanent heap),作为堆空间的一部分存在。介于此,我们可以简单说明一下我们常用的几个堆内存配置的参数关系:*-XX: PermSize:*永久堆(Pergen区域)大小默认值*-XX:MaxPermSize:*永久堆(Pergen区域)最大值*-Xms:*堆内存大小默认值*-Xmx:*堆内存最大值
运行时数据区访问方式总结
从开发者角度,虚拟机运行时数据区的访问方式简要归纳如下:
活动的线程可以通过对应的栈来访问运行时数据区信息
栈是堆访问的入口
堆上Java.lang.Class实例是访问PermGen区域中类型信息的入口
【示意图说明:】
一个类型装载之后会创建一个对应的java.lang.Class实例,这个实例本身和普通对象实例一样存储于堆中,我觉得之所以说是这是一种特殊的实例,某种程度上是因为其充当了访问PermGen区域中类型信息的代理者。
图中的Class类型实例和类加载器实例分别是A类型对应的java.lang.Class实例和加载A类型的类加载器实例。
只要是有active的对象实例句柄,就能够访问到对应的Class类型实例和类加载器实例,分别通过Object.getClass()方法和Class.getClassLoader()方法。
只要是有active的Class类型实例句柄,就能够访问到对应的类加载器实例。
PermGen内存溢出深入分析
在本部分,首先交代一下必要的前提知识,这也为理解后面的测试程序做铺垫。
前提知识
由不同的类加载器实例加载的类型可以等价为完全不同的类型,哪怕时同一类型类加载器的不同实例加载的,都会在PermGen区域分配相应的空间来存储类型信息
新类型加载时,会在PermGen区域申请相应的空间来存储类型信息,类型被卸载后,PermGen区域上的垃圾收集会释放对应的内存空间。PermGen区域和普通的堆空间一样,也遵循垃圾收集的规律,所以,网上很多资料种关于PermGen区域空间的大小是只增不减的说法是不正确的,后面会用相应的测试代码来验证和分析。
一种类型被卸载的前提条件是:加载此类
文档评论(0)