`
Rhain
  • 浏览: 7913 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

译文:解密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及web中英对照译文

    JavaServer Pages(JSP)是Java技术领域中用于构建动态网页的一种标准技术,由Sun Microsystems公司发起并由多家公司共同参与开发。JSP类似于微软的ASP技术,它允许开发者在HTML或XML文档中嵌入Java代码片段...

    javacv-1.5.3.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    java外文文献

    Java外文文献 ...Java语言是当今最流行的编程语言之一,它的设计目标是提供一个平台独立、简单易学、可扩展和高度安全的编程语言。Java语言的应用非常广泛,包括Android应用开发、Web开发、桌面应用开发等。

    Face Alignment by Explicit Shape Regression原文及译文

    通过译文,读者可以深入理解方法背后的理论和实现细节,这对于科研人员和开发者来说是非常有价值的资源。 总的来说,“显式形状回归”是一种强大的工具,它在面部对齐任务中展现了优秀的性能和鲁棒性。这篇论文及其...

    Java-WebSocket-1.5.1.jar中文-英文对照文档.zip

    ·本文档为双语同时展示,一行原文、一行译文,可逐行对照,避免了原文/译文来回切换的麻烦; ·有原文可参照,不再担心翻译偏差误导; ·边学技术、边学英语。 ·只翻译了该翻译的内容,如:注释、说明、描述、...

    practice:练习java的源码,包括牛客和LeetCode译文的一些

    4. **异常处理**:Java中的try-catch-finally语句块和异常类的使用,以及如何编写健壮的异常处理代码,都是实践项目中不可或缺的部分。 5. **IO流**:Java的输入/输出流系统对于读写文件、网络通信至关重要。源码中...

    Java 并发核心编程原文+译文

    2. **并发工具类**:Java 5引入了`java.util.concurrent`包,包含许多并发工具类,如`ExecutorService`、`Future`、`Semaphore`、`CountDownLatch`和`CyclicBarrier`等,它们提供了线程池、任务提交、同步控制等多种...

    Java-for-Anylogic-user译文

    本资源原文为java-for-Anylogic-user英文版,即面向Anylogic用户的Java开发,本人纯手工翻译,讲述以拖放方式以外的编程思路,对于建立复杂系统有很大帮助。这是一个信息论,可以在模型中进行数据操作以及智能体的...

    探讨计算机软件开发的JAVA 编程语言应用.doc,原文+译文。

    总结来说,Java编程语言在计算机软件开发中的应用主要得益于其跨平台能力、强大的类库支持、高效的内存管理和面向对象特性。从嵌入式系统到大型企业应用,Java都展现出了极高的适应性和灵活性,成为了现代软件开发中...

    javacv-1.5.6.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.4.1.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.3.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.3.3.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.0.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.3.2.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.5.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.5.8.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-1.5.1.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

    javacv-0.11.jar中文-英文对照文档.zip

    implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)...

Global site tag (gtag.js) - Google Analytics