什么是PermGen泄漏?

泄漏样品 接下来是对Java应用程序中特定类型的内存问题的实用介绍。 即–我们将分析导致java.lang.OutOfMemoryError:PermGen空间的错误 堆栈跟踪中的症状。

首先,我们将介绍理解该主题所需的核心概念,并说明什么是对象,类,类加载器和JVM内存模型。 如果您熟悉基本概念,则可以直接跳到下一部分,在此我将描述所讨论错误的两种典型情况以及解决它的提示和建议。

对象,类和类加载器

好吧,我不会从最基本的内容开始。 我想如果您已经找到我们,那么您应该熟悉Java中的一切都是Object的概念。 并且所有对象均由其类指定。 因此,每个对象都有对java.lang.Class实例的引用,该实例描述了该对象的类的结构。

但是,当您在代码中创建一个新对象时,实际上发生了什么呢? 例如,如果您写的东西真的很复杂

人老板=新人()

Java虚拟机(JVM)需要了解要创建的对象的结构。 为此,JVM查找名为Person的类。 而且,如果在程序的特定执行期间第一次访问Person类,则通常必须从JVM从相应的Person.class文件中加载它。 在驱动器上查找Person.class文件,将其加载到内存中并解析其结构的过程称为类加载 。 确保正确的类加载过程是ClassLoader的责任 ClassLoader是java.lang.ClassLoader类的实例,Java程序中的每个类都必须由某个ClassLoader进行加载。 结果,我们现在具有以下关系:

关系

从下图可以看到,每个类加载器均包含对其已加载的所有类的引用。 就本文而言,这些关系非常有趣。

参考资料

记住此图像,稍后我们将需要它。

永久世代

如今,几乎每个JVM都使用一个单独的内存区域(称为Permanent Generation(简称PermGen ))来保存Java类的内部表示形式。 PermGen还用于存储更多信息-如果您有兴趣,请从这篇文章中查找详细信息-但对于我们的文章,可以安全地假设仅类定义存储在PermGen中。 在运行Java 1.6的两台计算机上,该区域的默认大小不是非常可观的82MB。

正如我在之前的一篇文章中所解释的那样,Java中的内存泄漏是一种情况,其中某些对象不再被应用程序使用,但是垃圾收集器无法将其识别为未使用。 如果那些未使用的对象对堆使用的贡献很大,以致于应用程序无法满足下一个内存分配请求,则会导致OutOfMemoryError

java.lang.OutOfMemoryError:PermGen空间的根本原因是完全相同的:JVM需要加载新类的定义,但是PermGen中没有足够的空间来执行此操作–那里已经存储了太多的类。 可能的原因是,您的应用程序或服务器使用了太多的类,而PermGen的当前大小无法容纳它们。 另一个常见原因可能是内存泄漏。

永久泄漏

但是,仍然有可能在PermGen中泄漏某些东西吗? 它保存着Java类的定义,它们不能成为未使用的,可以吗? 实际上,他们可以。 如果将Java Web应用程序部署到应用程序服务器中,则在取消部署应用程序时,EAR / WAR中的所有这些类将变得毫无用处。 由于应用程序服务器仍处于活动状态,因此JVM继续运行,但是不再使用大量的类定义。 并且应该将它们从PermGen中删除。 如果没有,我们将在PermGen区域发生内存泄漏。

作为一个很好的例子,Tomcat开发人员已经建立了一个Wiki页面,描述了在Apache Tomcat 6.0.24及更高版本中发现并修复的各种漏洞。

泄漏线程

类加载器泄漏的一种可能情况是长时间运行的线程。 当您的应用程序或您的应用程序使用的第三方库(通常以我的经验)启动某个长时间运行的线程时,就会发生这种情况。 一个例子就是计时器线程,其任务是定期执行一些代码。

如果该线程的预期寿命不确定,我们将直接陷入麻烦。 当应用程序的任何部分启动线程时,必须确保它不会使应用程序寿命更长。 在典型情况下,开发人员要么不了解此责任,要么干脆忘了编写清理代码。

否则,如果在取消部署应用程序后某个线程继续运行,则通常将保留对由其启动的Web应用程序的类加载器的引用,称为上下文类加载器 。 反过来,这意味着未部署的应用程序的所有类都继续保留在内存中。 补救? 如果是您的应用程序启动了新线程,则应在取消部署期间使用servlet上下文侦听器将其关闭。 如果它是第三方库,则应搜索其自己的特定关闭挂钩。 或提交错误报告(如果没有)。

驱动程序泄漏

数据库驱动程序可能导致泄漏的另一种典型情况。 我们在Plumbr附带的演示应用程序中遇到了此泄漏。 它是随Spring MVC一起提供的经过稍微修改的Pet Clinic应用程序。 让我们重点介绍将应用程序部署到服务器时发生的一些事情。

  • 服务器创建一个新的java.lang.Classloader实例,并开始使用它加载应用程序的类。
  • 由于PetClinic使用HSQL数据库,因此它将加载相应的JDBC驱动程序org.hsqldb.jdbcDriver
  • 此类是一种很好的JDBC驱动程序,根据JDBC规范的要求,在初始化期间将其自身注册到java.sql.DriverManager 。 该注册包括在DriverManager的静态字段中存储对org.hsqldb.jdbcDriver实例的引用。

现在,当从应用程序服务器取消部署应用程序时, java.sql.DriverManager仍将保留该引用,因为HSQLDB库,Spring框架或应用程序中都没有删除该代码的代码! 如上文所述, jdbcDriver对象仍然持有对org.hsqldb.jdbcDriver类的引用,而该类又持有对用于加载应用程序的java.lang.Classloader实例的引用。 现在,该类加载器仍引用应用程序的所有类。 对于我们特定的演示应用程序,在应用程序启动期间将加载近2000个类,在PermGen中大约占用10MB。 这意味着需要大约5到10个重新部署才能用默认大小填充PermGen,以达到java.lang.OutOfMemoryError:PermGen空间崩溃。

如何解决? 一种可能性是编写一个Servlet上下文侦听器,该侦听器在应用程序关闭期间从DriverManager注销HSQLDB驱动程序。 这很简单。 但是请记住–您将必须使用驱动程序在每个应用程序中编写相应的代码。

使用我们的演示应用程序下载我们最新版本的Plumbr,并使用它来查找泄漏的发生方式,Plumbr如何发现泄漏以及如何解释原因。

结论

您的应用程序可能遇到java.lang.OutOfMemoryError:PermGen space的原因很多。 导致它们大多数的根本原因是对由应用程序的类加载器加载的对象或类的引用,这些对象或类在此之后死亡。 或直接链接到类加载器本身。 对于大多数这些原因,您需要采取的补救措施非常相似。 首先,找出引用在哪里保存。 其次,向您的Web应用程序添加一个关闭挂钩,以在取消部署应用程序时删除引用。 您可以通过使用Servlet上下文侦听器或通过第三方库提供的API来实现。

找到那些泄漏的参考从未如此简单。 我们自己花费了无数的时间试图找出为什么某些应用程序每次重新部署都需要20MB的PermGen。 但是从1.1版开始,Plumbr将向您显示泄漏的原因,并提示您如何修复它。 如果您想尝试一下,请注册并下载该工具 。 如果您运行的是Plumbr的旧版本,我们强烈建议您下载升级程序 。

参考: 什么是PermGen泄漏? 由我们的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上获得。

翻译自: https://www.javacodegeeks.com/2012/12/what-is-a-permgen-leak.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rto净化效率计算公式_全面剖析 石油化工行业RTO蓄热式焚烧炉的优势要素

在我国的国民经济发展中,石油化工产业是重要的能源基础工业,但是废气的治理问题一直困扰着许多企业。直到RTO蓄热式焚烧炉的面世,为石油化工行业的废气治理带来了新希望。如今,有机废气治理工作越来越受到广泛重视,传统…

python作业:高级FTP程序

要求: 用户加密认证允许同时多用户登录每个用户有自己的家目录 ,且只能访问自己的家目录对用户进行磁盘配额,每个用户的可用空间不同允许用户在ftp server上随意切换目录允许用户查看当前目录下文件允许上传和下载文件,保证文件一…

webpack学习笔记 (一)

一、安装nodejs; 点击打开nodejs官方站点; 点击下图框住的按钮,下周nodejs安装包; 安装下载好的安装包。 安装完毕之后,在cmd中输入node -v查看是否已经安装成功 如果有版本号显示,则代表安装成功&#xf…

将涡轮增压器添加到JEE Apps

我扮演的关键角色之一是在本地社区中传播Akka。 作为讨论的一部分,人们通常会想到的问题/疑问是Akka如何针对编写良好的Java / JEE应用程序提供更好的可伸缩性和并发性。 由于底层硬件/ JVM保持不变,因此参与者模型如何比传统的JEE应用程序发挥更多的功…

MapReduce的工作原理

一、MapReduce模型框架 MapReduce是一个用于大规模数据处理的分布式计算模型,最初由Google工程师设计并实现的,Google已经将完整的MapReduce论文公开发布了。其中的定义是,MapReduce是一个编程模型,是一个用于处理和生成大规模数据…

react实现多行文本超出加省略号

http://www.css88.com/archives/5206 overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; 根据该文章方法,放在react项目中发现并不能实现,仔细观察发现原来react解析出来的css样…

qq群 html,我的群组-普通群组.html

我的群组-普通群组$axure.utils.getTransparentGifPath function() { return resources/images/transparent.gif; };$axure.utils.getOtherPath function() { return resources/Other.html; };$axure.utils.getReloadPath function() { return resou…

查看PLC IP 端口_西门子828D数控系统X130接口通讯怪异现象(X130手动设置的 IP)...

西门子828D数控系统,调试PLC过程中遇到网络通信怪异问题(不能直连非要加个路由器),笔记本电脑的以太网网络直接连接显示网络电缆被拔出,如下图所示:奇怪,怎么出现这种情况了呢,因为我用这台电脑调试过别的P…

bzoj1263

贪心 n%31 分出一个4&#xff0c;其余用3&#xff0c;n%32&#xff0c;分出一个2&#xff0c;其余用3&#xff0c;然后高精度就行了 #include<bits/stdc.h> using namespace std; const int N 5005; struct BigInt {int len;int a[N];BigInt() { memset(a, 0, sizeof(a)…

c语言volatile_[技术]为什么单片机C语言编程时某一变量有时乱码

最近一个项目里面&#xff0c;在KEIL中用C语言在单片机里面定义了一个状态机全局变量&#xff0c;这个变量随时会改变&#xff0c;用于切换触摸屏的界面&#xff0c;可是程序运行中出现了一个问题&#xff0c;这个状态机号总是出现了被莫名奇妙改变的问题&#xff0c;导致触屏不…

微型计算机2017年9月上,2017年9月计算机一级考试WPS Office冲刺题

2017年9月计算机一级考试WPS Office冲刺题2017年下半年计算机一级考试将在9月份进行&#xff0c;为了方便考生备考计算机一级考试。下面是小编为大家带来的计算机一级考试WPS Office冲刺题&#xff0c;欢迎阅读。冲刺题一&#xff1a;1、PowerPoint 演示文稿和模板的扩展名是【…

11尺寸长宽 iphone_弱电工程LED显示屏尺寸规格及计算方法

前言&#xff1a;led屏幕在生活中&#xff0c;随处可见&#xff0c;显示屏、广播屏等等&#xff0c;但是led尺寸怎么计算的&#xff0c;你知道吗&#xff1f;今天我们一起了解一下led屏幕尺寸的计算方法。正文&#xff1a;一、点间距的计算1、各单元板常见型号及尺寸LED屏普遍是…

marquee标签的使用

<!DOCTYPE html> <html> <head><meta charset"utf-8" /><title>演示marquee</title><style type"text/css">*{padding: 0px;margin: 0px;}marquee{border: 1px solid purple;}img{width: 360px;height: auto;}&…

32位数据源中没有mysql_[SpringBoot实战]快速配置多数据源(整合MyBatis)

前言由于业务需求&#xff0c;需要同时在SpringBoot中配置两套数据源&#xff08;连接两个数据库&#xff09;&#xff0c;要求能做到service层在调用各数据库表的mapper时能够自动切换数据源&#xff0c;也就是mapper自动访问正确的数据库。本文内容&#xff1a;在SpringbootM…

考研计算机冷门学校,考研5个冷门的985院校 别随大流,这些几所也是很不错的...

导语&#xff1a;想必大家考研的目的有很多&#xff0c;最主要的就是想去更好的学校提升自己&#xff0c;大部分会肯定是会更倾向于985这类的院校&#xff0c;每年其实除了那些被“挤破头”的985院校&#xff0c;其实还有不少“低调”的985院校是非常值得报考的&#xff0c;下面…

名为 cursor_jinserted 的游标不存在_质量工程师必须了解的测量常识,你不知道怎么行...

01测量器具的分类测量器具是一种具有固定形态、用以复现或提供一个或多个已知量值的器具。按用途的不同量具可分为以下几类&#xff1a;1. 单值量具只能体现一个单一量值的量具。可用来校对和调整其它测量器具或作为标准量与被测量直接进行比较&#xff0c;如量块、角度量块等。…

bzoj4869

http://www.lydsy.com/JudgeOnline/problem.php?id4869 终于A了。。。参考了下dalao的代码。。。 拓展欧几里得定理&#xff0c;改了几次就不变了&#xff0c;但是用的时候要在快速幂里判是不是要用。 #include<bits/stdc.h> using namespace std; typedef long long ll…

一张图一个表——CSS选择器总结

CSS选择器总结&#xff1a; (这些表是一张图片^_^) 看底部 完整思维导图图片和表格的下载地址&#xff1a;https://download.csdn.net/download/denlnyyr/10597820 &#xff08;我不想选择要积分币下载的&#xff0c;但那里最低必须选择1个积分……&#xff09; 参考文献&…

native层 安卓_安卓逆向——拼xx协议java层分析

制丨阿星整理丨阿星老铁们大家好&#xff0c;今天小编给大家带来很实用的技巧叫拼xx协议java层分析&#xff0c;有啥不足的地方望大家指点指点&#xff01;首先抓包 反编译这个时间段我们方法剖析一下找到onclick 看他的走向找到方法的地方都是在进行写入 所以我们直接分析结果…

Java集合框架图

转载于:https://www.cnblogs.com/areyouready/p/6835279.html