OpenJPA:内存泄漏案例研究

本文将提供完整的根本原因分析详细信息以及解决影响Oracle Weblogic Server 10.0生产环境的Java堆内存泄漏(Apache OpenJPA泄漏)的方法。 这篇文章还将演示在管理javax.persistence.EntityManagerFactory生命周期时遵循Java Persistence API最佳实践的重要性。

环境规格

  • Java EE服务器 :Oracle Weblogic Portal 10.0
  • 操作系统 :Solaris 10
  • JDK :Oracle / Sun HotSpot JVM 1.5 32位@ 2 GB容量
  • Java Persistence API :Apache OpenJPA 1.0.x(JPA 1.0规范)
  • RDBMS :Oracle 10g
  • 平台类型 :Web门户

故障排除工具

  • Quest Foglight for Java( Java堆监视)
  • MAT(Java 堆转储分析 )

问题描述与观察

生产中断后,最初由Weblogic生产支持团队报告了此问题。 最初的根本原因分析练习确实揭示了以下事实和观察结果:

  • 约2周的流量后,定期观察到生产中断。
  • 失败是由于Java堆(OldGen)耗尽所致,例如OutOfMemoryError:在Weblogic日志中发现Java堆空间错误。
  • 在一段时间后从Foglight监视工具检查了Java堆OldGen的空间利用率以及Java冗长的GC历史数据后,确认了Java堆内存泄漏。

发现上述问题后,决定移至RCA的下一个阶段,并对受影响的Weblogic(JVM)实例执行JVM 堆转储分析 。

JVM堆转储分析

**现在可以在此处获得解释以下JVM堆转储分析的视频。 为了产生一个
JVM堆转储受支持的团队确实使用了HotSpot 1.5 jmap实用程序,该实用程序生成了大约1.5 GB的堆转储文件(heap.bin)。 然后使用Eclipse Memory Analyzer Tool分析了堆转储文件。 现在,让我们回顾一下堆转储分析,以便我们了解OldGen内存泄漏的根源。

MAT提供了一个初始的泄漏可疑报告,这对于突出您的高内存贡献者非常有用。 对于我们的问题案例,MAT能够识别出泄漏嫌疑人,造成了将近600 MB的泄漏或占OldGen空间总容量的40%。

至此,我们找到了一个java.util.LinkedList实例,该实例使用了将近600 MB的内存,并已加载到我们的应用程序父类加载器之一(@ 0x7e12b708)。 下一步是了解泄漏的对象以及保留的来源。 MAT允许您检查应用程序的任何类加载器实例,为您提供检查加载的类和实例的功能。 只需提供地址(例如0x7e12b708)来搜索所需的对象,然后通过选择带有外向引用的“列表对象”>检查加载的类和实例。

从上面的快照中您可以看到,该分析非常有启发性。 我们发现内存保留源中有一个org.apache.openjpa.enhance.PCRegistry实例; 罪魁祸首是实现为LinkedList的_listeners字段。 供您参考,Apache OpenJPA PCRegistry在内部用于跟踪已注册的具有持久性的类。 在Apache OpenJPA 1.0.4版中暴露_listeners字段的PCRegistry源代码的片段下面。

/*** Tracks registered persistence-capable classes.** @since 0.4.0* @author Abe White*/
public class PCRegistry {// DO NOT ADD ADDITIONAL DEPENDENCIES TO THIS CLASSprivate static final Localizer _loc = Localizer.forPackage(PCRegistry.class);// map of pc classes to meta structs; weak so the VM can GC classesprivate static final Map _metas = new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);// register class listenersprivate static final Collection _listeners = new LinkedList();

现在的问题是,为什么这种内部数据结构的内存占用空间如此之大,并且随着时间的推移可能会泄漏? 下一步是深入研究_listeners LinkedLink实例,以便检查泄漏的对象。

最后,我们发现泄漏的对象实际上是我们的应用程序用来对Oracle数据库执行各种查询的JDBC和SQL映射定义(元数据)。 对JPA规范,OpenJPA文档和源代码的回顾确实确认了根本原因与javax.persistence.EntityManagerFactory的错误使用有关,例如缺少关闭新创建的EntityManagerFactory实例。

如果仔细查看上面的代码快照,您将意识到close()方法确实负责清理最近使用的元数据存储库实例。 这也确实引起了另一个问题,为什么我们要一遍又一遍地创建这样的Factory实例……调查的下一步是对我们的应用程序代码执行代码遍历,尤其是围绕JPA EntityManagerFactory和EntityManager对象的生命周期管理。

根本原因和解决方案

该应用程序代码的代码演练确实表明该应用程序在每个单个请求上都创建了EntityManagerFactory的新实例,并且没有正确关闭它。

public class Application {@Resourceprivate UserTransaction utx = null;// Initialized on each application request and not closed!@PersistenceUnit(unitName = "UnitName")private EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersistenceUnit"); public EntityManager getEntityManager() {return this.emf.createEntityManager();}public void businessMethod() {// Create a new EntityManager instance via from the newly created EntityManagerFactory instance// Do something...// Close the EntityManager instance}
}

JPA EntityManagerFactory的此代码缺陷和改进程序的使用引起了OpenJPA _listeners数据结构内元数据存储库实例的泄漏或积累,这是从早期JVM堆转储分析中展示的。 该问题的解决方案是通过Singleton模式集中管理线程安全javax.persistence.EntityManagerFactory的管理和生命周期。 最终解决方案的实现如下:

  • 每个应用程序类加载器仅创建和维护一个javax.persistence.EntityManagerFactory静态实例,并通过Singleton Pattern实现。
  • 为每个应用程序请求创建并处置EntityManager的新实例。

请阅读Stackoverflow上的 讨论 ,因为我们实现的解决方案非常相似。 在将解决方案实施到我们的生产环境之后,不再观察到Java堆OldGen内存泄漏。

参考: OpenJPA:我们的JCG合作伙伴 Pierre-Hugues Charbonneau在Java EE支持模式和Java教程博客上的内存泄漏案例研究 。

翻译自: https://www.javacodegeeks.com/2013/03/openjpa-memory-leak-case-study.html

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

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

相关文章

以A表中的值快速更新B表中记录的方法

1、问题描述 有两张表,A表记录了某些实体的新属性,B表记录了每个实体的旧属性,现在打算用A中的属性值去更新B中相同实体的旧属性,如下图所示: 类似这样的需求,怎样做比较高效呢? 2、制作模拟数…

JAXB教程–入门

注意:请查看我们的Java XML绑定JAXB教程– ULTIMATE指南 什么是JAXB? JAXB代表用于XML绑定的Java体系结构。它用于将XML转换为java对象,并将java对象转换为XML。JAXB定义了一个用于在XML文档中读写Java对象的API。与SAX和DOM不同&#xff0c…

《Kubernetes权威指南第2版》学习(二)一个简单的例子

1: 安装VirtualBox, 并下载CentOS-7-x86_64-DVD-1708.iso, 安装centOS7,具体过程可以百度。 2:开启centOS的SSH, 步骤如下: (1) yum list installed | grep openssh-server查看是否已经安装了SS…

linux 安装ftp下载,LINUX FTP安装与配置

转载了一篇配置vsftpd服务器的文章,经过自己的配置,终于搞定了!1.安装vsftpdXml代码 yum install vsftpd2.启动/重启/关闭vsftpd服务器Xml代码 [rootlocalhost ftp]# /sbin/service vsftpd restartShutting down vsftpd: [ OK ]Starting vs…

使用Hibernate批量获取

如果需要从Java处理大型数据库结果集,则可以选择JDBC,以提供所需的低级控制。 另一方面,如果您已在应用程序中使用ORM,则回退到JDBC可能意味着额外的麻烦。 在域模型中导航时,您将失去乐观锁定,缓存&#x…

前端经典面试题 不经典不要star!

前言 (以下内容为一个朋友所述)今天我想跟大家分享几个前端经典的面试题,为什么我突然想写这么一篇文章呢?今天我应公司要求去面试了下几位招聘者,然后又现场整不出几个难题,就搜了一下前端变态面试题! HAHA,前提我并不是一个变态,欺负人的面试官.只是我希望看看对…

Web前端开发学习误区,你掉进去了没?

从接触网站开发以来到现在,已经有五个年头了吧,今天偶然整理电脑资料看到当时为参加系里面一个比赛而做的第一个网站时,勾起了在这网站开发道路上的一串串回忆,成功与喜悦、烦恼与纠结都历历在目,感慨颇多。 先从大家学…

spring mvc的工作原理

该文转载自:http://blog.csdn.net/u012191627/article/details/41943393 SpringMVC框架介绍 1) spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的…

使用IntelliJ IDEA的原因

介绍 我经常遇到一个问题,为什么我使用Intellij来支持另一个IDE(在本例中为Eclipse)。 大多数时候,我会通过演示IntelliJ的某些功能并展示一切的集成程度来回答这个问题。 这让我开始思考使用它的真正原因是什么。 这篇文章将试图…

linux光标美化包,使用 [ powerlevel10k ] 美化你的WSL (Linux)

使用 [ powerlevel10k ] 美化你的WSL (Linux)使用 [ powerlevel10k ] 美化你的WSL (Linux)前言关于linux终端的美化,网上的教程有很多,但对于国内的用户来说,效果往往是这样的:教程中通过以下命令安装 oh-my-zshsh -c "$(cur…

HashMap实现原理分析

1 HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是&#xf…

opencv3.2.0在vs2015下安装与配置

准备工作 VS2015OpenCV 3.2.0OpenCV配置环境变量,path下添加\opencv\build\x64\vc14\bin,新设置的环境变量需要重启才能使用测试工程 新建VC控制台空项目修改平台为x64,这一步先做源文件中加入main.cpp,测试代码:#incl…

如何使用字节序列化双精度数组(二进制增量编码,用于低差单调浮点数据集)...

低延迟系统需要高性能的消息处理和传递。 由于在大多数情况下,数据必须通过有线传输或进行序列化才能保持持久性,因此编码和解码消息已成为处理管道的重要组成部分。 高性能数据编码的最佳结果通常涉及应用程序数据细节的知识。 本文介绍的技术是一个很好…

微信小程序 引入公共页面的几种情况

1、不带参数 首先在pages文件夹中新建一个template文件夹&#xff0c;文件夹中新建一个template.wxml文件&#xff0c;代码如下 <!--template.wxml--> <template name"msgItem"><view><text>This is template.wxml文件&#xff0c;我是一个…

易语言自定义数据类型转c,一步一步跟我学易语言之自定义数据类型

自定义数据类型什么是“自定义数据类型”&#xff1f;顾名思义&#xff0c;就是用户可以随时在程序中自行定义新的数据类型。自定义数据类型时需要设置数据类型的名称及其成员。数据类型成员各属性的设置方法等同于变量设置时相应属性的设置方法。双击“程序”中的“自定义数据…

Redis初步整理

1&#xff0c;Redis 简介 Redis 是完全开源免费的&#xff0c;遵守BSD协议&#xff0c;是一个高性能的key-value数据库。 Redis 与其他 key - value 缓存产品有以下三个特点&#xff1a; Redis支持数据的持久化&#xff0c;可以将内存中的数据保持在磁盘中&#xff0c;重启的时…

阶段十-物业项目

可能遇到的错误&#xff1a; 解决jdk17javax.xml.bind.DatatypeConverter错误 <!--解决jdk17javax.xml.bind.DatatypeConverter错误--><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>…

echarts中triggeron与trigger不能同时出现吗_好物|痛风、血糖高、虚不受补能吃它吗?你想知道的阿胶十问十答一锅出!...

最近百草君在整理粉丝留言的时候&#xff0c;发现关于阿胶四物膏的留言不少&#xff0c;并且有重复问题。百草君特意整理出来几个粉丝们特别关注的问题&#xff0c;给大家统一解答&#xff0c;顺序不分前后&#xff1a;Q1阿胶四物膏什么口感&#xff0c;甜不甜&#xff1f;阿胶…

【移动端 Web】怎么循序渐进地开发一个移动端页面

1. 移动页面开发基础 1.1 像素——什么是像素 像素是 Web 页面布局的基础&#xff0c;那么到底什么才是一个像素呢&#xff1f; 像素&#xff1a;一个像素就是计算机屏幕所能显示一种特定颜色的最小区域。这是像素的概念&#xff0c;实际上&#xff0c;Web 前端开发领域&…

带有Spring的JavaFX 2

我将从一个大胆的声明开始&#xff1a;我一直很喜欢Java Swing或applet。 在那里&#xff0c;我说了。 如果我进行一些自我分析&#xff0c;那么这种钦佩可能是在我入门Java时开始的。 Swing&#xff08;实际上&#xff09;是我使用Java所做的第一件事&#xff0c;它给出了一些…