一.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

Java内存不足之PermGen space错误探究相关推荐

  1. 元空间不足java.lang.OutOfMemoryError: PermGen space 错误的原因及解决方法

    出现 java.lang.OutOfMemoryError: PermGen space 错误的原因及解决方法 原因:堆内存的永久保存区内存分配不足(缺省默认为64M),导致内存溢出错误. 解决的方案 ...

  2. PermGen space错误解决方法

    2.报错: Exception in thread "DispatcherThread" java.lang.OutOfMemoryError: PermGen space Exc ...

  3. linux tomcat6 permgen space,tomcat内存溢出之PermGen space

    线上一台web服务器不能正常访问了,检查了一下,tomcat进程还在,就是web不能正常访问,重启一下tomcat恢复正常,查询日志,发现提示内存溢出,如下图: java.lang.OutOfMemo ...

  4. java 获取permgen_[Java] 使用Java Visual VM寻找PermGen Space的解决办法

    在Eclipse使用tomcat运行3个项目时,老是报这个错误,以下为错误详情: 2014-5-28 13:47:41org.apache.catalina.core.StandardWrapperV ...

  5. tomcat-内存溢出java.lang.OutOfMemoryErrory:PermGen space解决方法

    如果是PermGen space方法区内存溢出,可尝试加大MaxPermSize,如果是heap space 堆内存移除,可尝试修改Xmx 正常解决方法: 在注释下的第一行添加: JAVA_OPTS= ...

  6. 如何排查Java内存泄露(内附各种排查工具介绍)

    今天刚刚才加一个故障review会议, 故障非常典型, google下也可以找到相似案例介绍. 在排查问题的过程中,使用了大量的工具, 发现有问题的地方还不只一个,总结一下. (本篇文章不会重点描述案 ...

  7. java.lang.OutOfMemoryError: PermGen space及其解决方法

    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决 ...

  8. 解决 PermGen space Tomcat内存设置

    2019独角兽企业重金招聘Python工程师标准>>> 在使用Java程序从数据库中查询大量的数据或是应用服务器(如tomcat.jboss,weblogic)加载jar包时会出现j ...

  9. HTTP Status 500 - javax.servlet.ServletException: java.lang.OutOfMemoryError: PermGen space

    详细错误信息 HTTP Status 500 - javax.servlet.ServletException: java.lang.OutOfMemoryError: PermGen spacety ...

最新文章

  1. 架设搭建开源搜索服务器 - Sphinx/Coreseek 安裝
  2. Notepad++ 快捷键 大全
  3. Java中J.U.C扩展组件之Fork,join
  4. android am命令用法
  5. C++--第19课 - 专题三经典问题解析
  6. MySQL查询优化和索引优化学习笔记
  7. 对接码是什么意思_聊聊API:API对接是什么意思 API接口程序介绍
  8. 云桌面选不对,再好的产品也白用
  9. winform日历控件
  10. Java前后端分离项目部署
  11. 数据质量六大评价标准
  12. 美通企业日报 | 三大因素最影响职场女性心理健康;Instagram重要性超过推特脸书...
  13. 利用opencv剪切图片
  14. 拿走不谢,最全匹配中国大陆手机号码的正则表达式
  15. POS标记——HMM模型
  16. 勇者与羁绊 游戏开发日志(一)
  17. kubeadm集群化部署多master节点(生产环境适用)
  18. 信息化管理系统(制造业ERP系统)
  19. 【Matlab 绘图——持续补充中】
  20. iMazing2023官网中文版下载及许可证附使用教程

热门文章

  1. 电压源和电流的关联参考方向_数控电压、电流源1.3
  2. rabbitmq direct 多个消费者_RabbitMQ实战应用技巧
  3. 数据结构之排序算法:并归排序
  4. 计算机网络之物理层:2、码元、速率、带宽、波特
  5. 网页文字无法复制解决方法
  6. C#删除字符串倒数第几个字符后的所有字符串
  7. Centos系统镜像下载
  8. C 控制父、子进程的先后顺序执行
  9. Python内置函数(49)——isinstance
  10. 《C程序设计语言》笔记 (五) 指针与数组