凉山建设网站,微信小程序模板 免费模板平台,保定手机网站,可以货代从哪些网站开发客户permgen接下来是对Java应用程序中特定类型的内存问题的实用介绍。 即–我们将分析导致java.lang.OutOfMemoryError#xff1a;PermGen空间的错误 堆栈跟踪中的症状。 首先#xff0c;我们将介绍理解该主题所需的核心概念#xff0c;并解释什么是对象#xff0c;类#… permgen 接下来是对Java应用程序中特定类型的内存问题的实用介绍。 即–我们将分析导致java.lang.OutOfMemoryErrorPermGen空间的错误 堆栈跟踪中的症状。 首先我们将介绍理解该主题所需的核心概念并解释什么是对象类类加载器和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.OutOfMemoryErrorPermGen空间的根本原因是完全相同的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.OutOfMemoryErrorPermGen空间崩溃。 如何解决 一种可能性是编写一个Servlet上下文侦听器该侦听器在应用程序关闭期间从DriverManager注销HSQLDB驱动程序。 这很简单。 但是请记住–您将必须使用驱动程序在每个应用程序中编写相应的代码。 使用演示应用程序下载我们最新版本的Plumbr并进行操作以了解泄漏的发生方式Plumbr如何发现泄漏以及如何解释原因。 结论 应用程序可能会遇到java.lang.OutOfMemoryErrorPermGen 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.htmlpermgen