如何在 Tomcat 上使用 JPA、Hibernate 和 Spring 避免类加载器泄漏

2023-12-03

The 打开 J2EE Web 模板是一个展示应用程序 wicket - 在 Tomcat7 servlet 容器上运行的带有 Spring 和 Hibernate 的 JPA.它的 Maven 构建脚本似乎以标准方式使用组件。

但是,当从 Tomcat 取消部署时,它会受到应用程序类加载器内存泄漏的影响。

Tomcat 的“查找泄漏”按钮确认了泄漏。当使用 VM 选项 -XX:+HeapDumpOnOutOfMemoryError 部署在 Tomcat 上时,可以使用 Eclipse 内存分析器工具 (MAT) 分析生成的堆转储。 MAT 识别类别java.util.logging.Level$KnownLevel作为阻止垃圾收集的罪魁祸首。

调试KnownLevel构造函数显示以下堆栈跟踪:

java.util.logging.Level$KnownLevel.add(Level.java:477) java.util.logging.Level。(Level.java:212) java.util.logging.Level。(Level.java:190) org.jboss.logging.JDKLevel。(JDKLevel.java:35) org.jboss.logging.JDKLevel。(JDKLevel.java:42) org.jboss.logging.JDKLogger.translate(JDKLogger.java:78) org.jboss.logging.JDKLogger.isEnabled(JDKLogger.java:85) org.jboss.logging.Logger.debugf(Logger.java:563) org.jboss.logging.LoggerProviders.find(LoggerProviders.java:37) org.jboss.logging.LoggerProviders.(LoggerProviders.java:32) org.jboss.logging.Logger.getLogger(Logger.java:2163) org.jboss.logging.Logger.getMessageLogger(Logger.java:2259) org.jboss.logging.Logger.getMessageLogger(Logger.java:2214) org.hibernate.ejb.Ejb3Configuration。(Ejb3Configuration.java:144) org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74) org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:268) org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567) org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385) org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284) org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)

如果我明白的话类加载器泄漏:可怕的“java.lang.OutOfMemoryError:PermGen space”异常正确的话,那么这个类加载器泄漏是可以预料的。

避免这种情况的推荐方法是什么,或者替代 Spring/JPA 是什么 Tomcat 上的模板 Web 应用程序?


我在 Tomcat7 + OpenJPA2.4.1 + ValidationAPI1.x + hibernate-validator-5.2.1 + jboss-logging.jar 上看到了同样的 webapp 内存泄漏

问题确实是 jboss-logging.jar 创建了 java.util.logging.Level 实例的子类。如果 jar 由 J2EE 容器提供,则可能不是问题,但在 mywebapp/WEB-INF/lib 分发中会出现问题。我创建了一个包的分支禁用子类化。问题消失了,webapp 热重新部署工作正常。

GC 根路径的 Heapdump 表明了问题的根源,JDKLevel 子类将 Web 应用程序保留在内存中,很快 JVM 就会耗尽 PermGen 内存。

this     - value: org.apache.catalina.loader.WebappClassLoader #2
 <- <classLoader>     - class: org.jboss.logging.JDKLevel, value: org.apache.catalina.loader.WebappClassLoader #2
  <- <class>     - class: org.jboss.logging.JDKLevel, value: org.jboss.logging.JDKLevel class JDKLevel
   <- levelObject     - class: java.util.logging.Level$KnownLevel, value: org.jboss.logging.JDKLevel #6
    <- [1]     - class: java.lang.Object[], value: java.util.logging.Level$KnownLevel #12
     <- elementData     - class: java.util.ArrayList, value: java.lang.Object[] #5160 (10 items)
      <- value     - class: java.util.HashMap$Entry, value: java.util.ArrayList #3532
       <- [0]     - class: java.util.HashMap$Entry[], value: java.util.HashMap$Entry #21639
        <- table     - class: java.util.HashMap, value: java.util.HashMap$Entry[] #280 (16 items)
         <- intToLevels (sticky class)     - class: java.util.logging.Level$KnownLevel, value: java.util.HashMap #375

edit为此错误创建了 JBoss Jira 票证(https://issues.jboss.org/browse/JBLOGGING-118)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Tomcat 上使用 JPA、Hibernate 和 Spring 避免类加载器泄漏 的相关文章

随机推荐

  • 有人可以解释哈希表的 Add_member 和 $hashTable.Something 之间的区别吗?

    假设我有一个哈希表 HashTable 现在 当我想向哈希表添加一些内容时 我通常会这样做 HashTable Something Something 当我测试 hashTable 时 它 将显示以下输出 HashTable Name Va
  • 如何转义 LIKE 子句?

    在搜索查询的这一部分中 我们使用的代码很简单 myCriteria Add Expression InsensitiveLike Code itemCode MatchMode Anywhere 这在生产环境中工作得很好 问题是我们的一位客
  • 是否有符合 POSIX 标准的方法来获取我的计算机的本地网络 IP 地址?

    我知道这个问题已经以这样或那样的形式被问了一百万次 但没有一个问题给了我一种符合 POSIX 的方式来做到这一点 我需要获取我的计算机的本地网络地址without using getifaddrs或任何其他不符合 POSIX 标准的访问接口
  • RichFaces 文件上传和 h:message 问题

    我正在使用 RichFaces 4 我的问题是该消息根本不出现 如果我使用 rich message 该消息会短暂出现然后消失 这是控制器 public void uploadListener final FileUploadEvent e
  • Zend Framework 2 bin 文件夹中“Zend Tool Missing”

    我是框架新手 但我在安装 zend 1 x 版本等方面没有任何困难 但是ZF2真的搞不懂 任何资源告诉我使用 zend 工具创建项目 即 bin 目录中的 zf bat 或 zf sh 但与 zf1 相比 zf2 bin 文件夹中没有它们
  • 在Cypress(mysql2)中测试时无法连接到MySQL数据库

    运行集成测试时出现错误 0 passing 17s 1 failure 1 Registration page register new users allowed and update status in the database Typ
  • 多个三元运算符

    我需要一些关于三元运算符的语法帮助 这将帮助我将正确的标记图标放在我的好地图上 我有三个区域 0 1 和 2 它们具有独特的图标 0 1 和 2 我以前只有两个区域 所以这个三元运算符工作得很好 var icon area 1 icon1
  • 在 Projection.Conditionals 中添加多个条件以进行查询

    我正在尝试写一个包含多个的案例when条款 像这样的东西 case when starks then 1 when wildlings then 2 when lannisters then 3 Else 0 End 我以前做过一个条件条件
  • GeventSocketIOWorker 没有属性“socket”

    我需要使用 Gunicorn 运行 Django 应用程序 我阅读了文档 我想我已经按照我应该的方式设置了所有内容 但是当我运行时 gunicorn worker class socketio sgunicorn GeventSocketI
  • Date.addingTimeInterval(_:) 和 Date.advanced(by:) 有什么区别?

    基金会的Datestruct 提供了两者Date addingTimeInterval and Date advanced by 它们在功能上似乎相同 但显然是不同的方法 它们之间实际上有区别还是最终相同 查看文档 advanced by
  • 使用 Tensorflow-Hub 中的 ELMo 时内存消耗大幅增加

    我目前正在尝试比较数百万个文档的相似性 对于 CPU 上的第一次测试 我将它们减少到每个字符大约 50 个 并尝试一次为其中 10 个字符获取 ELMo 嵌入 如下所示 ELMO https tfhub dev google elmo 2
  • Mockito、JUnit 和 Spring

    我今天才开始了解Mockito 我编写了一些简单的测试 使用 JUnit 见下文 但我不知道如何在 Spring 的托管 bean 中使用模拟对象 什么是最佳实践用于与 Spring 一起工作 我应该如何向我的 bean 注入模拟依赖项 你
  • 找不到 Microsoft.AspNet.SignalR.Server 3.0.0-beta7

    我在引用包时遇到问题 Microsoft AspNet SignalR Server 3 0 0 beta7 我唯一可以安装的是 测试版 5 版本 我在网上看到过其他例子 人们do引用这个 beta7 包 但我似乎找不到它 下面是我当前的
  • gdb 如何启动汇编编译的程序并一次执行一行?

    Valgrind 在他们的文档页面上说了以下内容 然后 您的程序将在 Valgrind 核心提供的合成 CPU 上运行 然而GDB似乎并没有这样做 它似乎启动了一个独立执行的单独进程 据我所知 也没有c 库 这就是我所做的 使用 clang
  • 删除sequelize返回值中的连接表数据

    我目前正在尝试删除一个joint检索关联数据时添加的表数据 查询是通过使用通过指定模型关系添加到模型的方法的sequelize来完成的 sequelize magic methods 由于某种原因 我无法做到这一点 我目前已尝试传递attr
  • Python 替换单引号(撇号除外)

    我正在对单词列表执行以下操作 我从古腾堡项目文本文件中读取行 用空格分割每一行 执行一般标点符号替换 然后在其自己的行上打印每个单词和标点符号标签 以便稍后进一步处理 我不确定如何用标签替换每个单引号或排除所有撇号 我当前的方法是使用编译的
  • SQL Server 2005:从 WHERE 子句调用存储过程

    我需要在 WHERE 子句中调用存储过程来进行 SELECT 应该是这样的 选择不同的前 10 名 i x d droit 来自 v droit d v info i WHERE d nomdroit yy AND i id2 AND 从
  • 转移矩阵

    考虑以下数据框 df data frame cusip paste A 1 10 sep xt c 1 2 3 2 3 5 2 4 5 1 xt1 c 1 4 2 1 1 4 2 2 2 5 数据分为五个州 哪个是分位数事实上 1 2 3
  • 无法读取未知加载命令0x80000022

    在我的应用程序中 我使用了大量从 Apple 的 SpeakHere 示例中复制的代码 当我在 iPhone 设备上运行该应用程序时 它在加载 XIB 之前会抛出此错误大约一百次 unable to read unknown load co
  • 如何在 Tomcat 上使用 JPA、Hibernate 和 Spring 避免类加载器泄漏

    The 打开 J2EE Web 模板是一个展示应用程序 wicket 在 Tomcat7 servlet 容器上运行的带有 Spring 和 Hibernate 的 JPA 它的 Maven 构建脚本似乎以标准方式使用组件 但是 当从 To