permgen_什么是PermGen泄漏?

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

permgen

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

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

相关文章

TP、PHP同域不同子级域名共享Session、单点登录

TP、PHP同域不同子级域名共享Session、单点登录 目的: 为了部署同个域名下不同子级域名共享会话,从而实现单点登录的问题,一处登录,同域处处子系统即可以实现自动登录。 PHP支持通过设置cookie使得同域不同子域共享SESSION 1. 通…

html语言书写注意事项,HTML注意事项(学习笔记)

1、在所有浏览器中都是有效的,但使用 其实是更长远的保障。类似的标签也一样2、标签最好用小写,未来的版本中可能强制用小写3、标签属性始终为属性值加引号属性值应该始终被包括在引号内。双引号是最常用的,不过使用单引号也没有问题。在某些…

UTF-8、GB2312、GB18030、GBK和BIG5等字符集编码范围的具体说明

一预备知识 1,字符:字符是抽象的最小文本单位。 它没有固定的形状(可能是一个字形),而且没有值。 “A”是一个字符,“”(德国、法国和许多其他欧洲国家通用货币的标志)也是一个字…

使用Forge,WildFly Swarm和Arquillian开发微服务

在本文中,我们将看到如何使用WildFly Swarm和Forge开发微服务,以及如何使用Arquillian和Rest Assured对其进行测试。 WildFly Swarm提供了一种创新的方法来打包和运行Java EE应用程序,方法是将它们与足够的服务器运行时一起打包以“ java -j…

html页面加载时触发的方法,在页面加载时触发onchange html事件

好的,我在select字段上有一个onchange事件。它现在很棒。当下拉“网络”更改时,它会刷新第二个下拉列表。我还希望顶部的ajax代码在页面加载和onchange上触发,以便填充第二个列表。这是因为它在编辑页面上。这是使用第一个的ajax调用function…

PYTHON-进阶-编码处理小结

开始 用python处理中文时,读取文件或消息,http参数等等 一运行,发现乱码(字符串处理,读写文件,print) 然后,大多数人的做法是,调用encode/decode进行调试,并没有明确思考为何出现乱码…

华为鸿蒙话题作文800字,关于鸿蒙OS 华为最高层发布最新通知:统一口径-华为,智能手机,鸿蒙...

6月2日晚,华为正式推出了HarmonyOS(鸿蒙操作系统),引发了国内外空前关注。OS操作系统是中国手机甚至整个科技行业的弱点,因此鸿蒙OS带来的震撼及争议都很多,甚至华为内部员工对它的认知也不相同。为此华为总裁办昨天发布了题为《关…

8-4 Fabled Rooks uva11134

题意:你的任务是在n*n的棋盘上放 n 小于5000 个车 使得任意两个车不互相攻击 且第i个车在一个给定的矩形ri之内 给出该矩形左上角坐标和右下角坐标四个点 必须满足放车的位置在矩形内 边上也行 如果无解输出IMPSSIBLE 行与列是独立的 所以可以分割成两个一模一…

谷歌guava_Google Guava MultiMaps

谷歌guava番石榴 这是我尝试解释和探索Google很棒的Guava java库的系列文章中的第一篇。 我在搜索Apache Commons Collections的通用版本时遇到了番石榴(Guava)–我需要一个Bimap并且厌倦了必须使用强制类型转换来填充我的代码–但是我发现要好得多。 …

python 获取系统相关编码的函数

怎么避免UnicodeEncodeError: ‘ascii’ codec can’t…类似的错误? 1、首先在py文件头部指定文件内容编码,例如:# coding: utf8 2、文件保存的时候要和py文件头部编码一致 3、在用decode和encode的时候,一定要确认要转换的字符原…

百度的html代码是什么,百度网页源代码是什么?

2017-07-28Java抓取网页的内容代码是什么public static String getHtmlReadLine(String httpurl){String CurrentLine”";String TotalString”";InputStream urlStream;String content”";try {URL url new URL(httpurl);// URL url new URL(“http://www。 …

html中高与行高的区别,深入了解css的行高Line Height属性

什么是行间距?古时候我们是用印刷机来处理文字,印出来的每个字都位于独立的一个块里。行间距,即传说中控制两行文字之间垂直距离的东东。在CSS,line-height被用来控制行与行之间的垂直距离。不过行间距与半行间距还是取决于CSS中的…

自动生成优化的Java类专业知识

如果您今年访问过JavaOne,您可能已经参加了我的演讲“如何从数据库生成定制的Java 8代码”。 在那次演讲中,我展示了如何使用Speedment Open Source工具包使用数据库作为域模型来生成各种Java代码。 我们没有时间要考虑的一件事是,Speedment不…

vue动态路由配置,vue路由传参

如果是不同的组件过来的,可以设置不同的id值,只要在目标组件获取属性id的值就可以了,参数就利用query.属性值来获取 转载于:https://www.cnblogs.com/xiaoqi2018/p/10434318.html

Linux Netcat 命令——网络工具中的瑞士军刀

netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据。通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它。使用netcat命令所能完成的事情令人惊讶。 netcat所做的就是在两台电脑之间建立链接并返回两个数据流,在这之后…

win10怎么放计算机在桌面,win10我的电脑怎么放在桌面

win10我的电脑图标怎么放在桌面呢?一不小心将win10桌面上的此电脑图标删除了,找了半天都没找到它。win10系统怎么将我的电脑图标藏的隐蔽。今天,我就将找回win10我的电脑图标方法分享给你们刚重装完win10系统有些小伙伴就急急忙忙的来询问小编…

project 2013 显示标题

1、分析 右键只能插入任务,不能插入标题,而插入任务会被编号,目前只能在打印设置标题,不能在编辑界面显示标题的,或者使用最高级任务的方式 2、解决 文件,打印,页面设置,页眉&#x…

getopt在Python中的使用

在运行程序时,可能需要根据不同的条件,输入不同的命令行选项来实现不同的功能。目前有短选项和长选项两种格式。短选项格式为"-"加上单个字母选项;长选项为"--"加上一个单词。长格式是在Linux下引入的。许多Linux程序都支…

大数据的数据采集数据处理_让我们处理大数据

大数据的数据采集数据处理作为开发人员,我们的重点是简单,有效的解决方案,因此,最有价值的原则之一就是“保持简单和愚蠢”。 但是使用Hadoop map-reduce很难坚持这一点。 如果我们要评估多个Map Reduce作业中的数据,我…

怎样正确使用和维护微型计算机,下篇:微型计算机应该怎样进行维护与保养

2. 养成良好的使用维护习惯(1)正确的使用习惯个人使用习惯对计算机的影响很大,首先是要正常开关机,开机的顺序是,先打开外设的电源,然后再开主机电源。关机顺序相反,先关闭主机电源,再关闭外设电源。其道理…