记一次kettle6升级kettle8引发的内存泄漏

标签: kettle6 升级 kettle8 | 发表时间:2019-10-11 17:28 | 作者:chenshangge
出处:https://www.iteye.com

起因

基于一些原因,需要将kettle6.1升级到新版的kettle8.2。升级后发现kettle8每隔几天出现

GC overhead limit exceeded 或者 OutOfMemoryError:Java heap space;

一开始猜测kettle8为了提高性能,而牺牲更多的堆内存,便从开始的Xmx2048m 增加到 Xmx4096m.

可是没过几天还是一样出现问题,又从4096m增加到6144m.

问题依旧得不到解决.

 

通过排查日志发现内存溢出的问题发现: 定时重复执行的作业出现数据库连接不上,

导致好几天的作业一直都在报错数据库连接拒绝,一直到内存溢出,kettle奔溃.

排查发现,只要作业是正常执行,kettle8.2就不会出现内存溢出的问题.

但是只要有作业一直报异常,那么只要1-2天(也可能更短,看作业执行频率),

kettle8.2就会内存溢出挂掉,

kettle6.1不会出现此种情况.

 

场景重现

测试环境部署kettle8.2,模拟重现.

在kettle8.2 启动脚本增加 

-Dcom.sun.management.jmxremote.port=9008 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

本地jconsole可以远程实时监控kettle运行时的内存与线程情况

增加

-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n

本地idea可以远程debug

 

在idea中git clone kettle8.2的源码.

 

往kettle上发了10个作业,每隔5秒重复执行.其中9个作业是正常执行的,

1个作业连接一个不存在的数据库,会一直报连接拒绝错误

jconsole监控如下图



 

红框时间区间是该错误job停用的时间段,期间内存能维持稳定。
在测试服务器上使用命令jmap -heap,发现老年代内存居高不下,无法回收。

 

排查

 

再使用命令jmap -histo:live >> a.log(JVM会先触发gc)排查哪些对象没有被回收

 

           327          83712  org.pentaho.di.trans.Trans

           327          20928  org.pentaho.di.trans.steps.selectvalues.SelectValuesMeta

           327          20928  org.pentaho.di.trans.steps.tableinput.TableInputMeta

           327          31392  org.pentaho.di.trans.steps.insertupdate.InsertUpdateMeta

           866          27712  org.pentaho.di.trans.TransHopMeta

 

基本上可以断定是每次错误执行的作业中的转换(trans)没有被GC回收。

但是仅根据堆内存中的对象数量无法判断是哪里还在引用这些对象。

 

使用命令 jmap -dump:live,format=b,file=./dump.dat 生成内存镜像

使用命令 jhat -J-Xmx1024M ./dump.dat (jdk自带分析工具)

执行后等待console 中输入start HTTP server on port 7000 即可使用浏览器访问 IP:7000

 



随机查看了几个引用trans对象的对象,看不出什么

kettle的对象互相引用太多太复杂,jhat这个工具很难直观找到最上层的引用对象

 

下载dump文件到本机,使用eclipse的插件 memory anaylize 分析dump

如下图


在树形图上容易trans对象没有被回收是因为被最上层的HashMap引用

 

在树形图中找到容易定位问题代码对象是

org.pentaho.osgi.blueprint.collection.utils.ServiceMap

查看源码,猜测作业执行异常的情况,没有执行itemRemoved方法,导致本该被回收的对象在内存越积越多

在源码中新增、修改两个方法打上断点,开启远程debug 如下图

 

调试一个正常的作业和错误的作业,发现确实如推测的,执行报错的作业最终没有执行itemRemoved.

调试过程跳过

定位具体代码 org.pentaho.di.trans.Trans

 

  public void execute( String[] arguments ) throws KettleException {
    prepareExecution( arguments );
    startThreads();
  }

 

 正常执行的job 会在 prepareExecution方法中的transMeta.setEmbeddedMetastoreProviderKey(....)

中调用serviceMap的itemAdded()

并在startThreads()方法中的transMeta.disposeEmbeddedMetastoreProvider()中

调用serviceMap的itemRemoved()

 

异常的job会在prepareExecution方法中初始化step时抛出数据库连接异常,导致后续不会进入到startThreads().

 

这下内存溢出的问题明确了,稍微修改源码,打包替换原先的kettle-engine.8.2.0.jar.

至此,kettle8.2内存泄漏问题彻底解决

后续

1、对比kettle6和kettle8的源码,发现了 EmbeddedMetastoreProvider   
   是kettle8新增的一个点,所以kettle6此场景的内存泄漏
2、测试过kettle8.3,也存在与8.2一样的内存泄漏问题.

 

 

 

 

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [kettle6 升级 kettle8] 推荐:

记一次kettle6升级kettle8引发的内存泄漏

- - 开源软件 - ITeye博客
基于一些原因,需要将kettle6.1升级到新版的kettle8.2. 升级后发现kettle8每隔几天出现. GC overhead limit exceeded 或者 OutOfMemoryError:Java heap space;. 一开始猜测kettle8为了提高性能,而牺牲更多的堆内存,便从开始的Xmx2048m 增加到 Xmx4096m.

我不升级

- Joro - 不许联想
昨天准备上QQ收文件,发现这样提示,我知道这个提示意味着什么,我犹豫了一下,最后选择不升级. 这意味着我不能再使用这个软件了. 最近腾讯和360之间充满龌龊和恶心的争斗,让我觉得越来越无聊了. 实际上,双方这样敢大打出手,都认为自己可以挟持用户,以达到自己的利益. 我估计双方都会在占有用户硬盘空间而没完没了地升级,相互给对方下绊,那用户的系统安全谁来保障呢.

Google wallet 升级了

- ROY - 谷奥——探寻谷歌的奥秘
(图片摘自Engadget). Google周一在它移动支付服务上增添了一些新功能,希望借此来吸引更多的商家. 现在顾客可以使用带有Google钱包的手机来兑换折扣券及累积积分,来享受轻轻一触带来的便利. 这是今年夏天Google钱包发布后的第一个强化功能,能让顾客在药店、零售店、出租车和部分火车站特别的支付终端上使用手机来付款.

从Windows 1.0升级到Windows7

- Sheriff - Solidot
一位勇敢的操作系统研究者发布了一则YouTube视频(YouTube,Youku),展现了从Windows 1.0一路升级到Windows7的经过. 作者是在一个VMWar虚拟机上安装微软的操作系统,视频展示了DOS和Windows的安装,通过安装一些DOS游戏来观察较新的操作系统是如何处理向后兼容性的,以及Windows中偏好设置是如何在升级中保留下来的.

Mac OS X 10.6.8 升级

- 子奇 - Engadget 中国版
看来 Apple 还打算让 Lion 上阵前再撑一阵子,Mac OS X 10.6.8 升级软件现在已经可以下载,修正了一些操作系统的问题,支持 IPv6 的一些功能以及加强 VPN 稳定度,另外也会自动找出并移除 Mac Defender 恶意软件及其已知变体,并解决预览程序有时会自动跳出的问题.

Chrome Beta 升级到 14.0.835.159

- 安得米 - 谷奥——探寻谷歌的奥秘
全平台的 Chrome Beta 升级到了14.0.835.159,这个版本最大的变化是禁用了 chrome:flags,原因是 Google 的工程师怀疑过多的使用实验室项目导致了 Chrome 最近的不稳定,所以他们决定暂时关闭实验室看看效果. 另外,全平台的 Dev 分支也统一更新到了 15.0.874.5,具体更新内容和昨天的一样.

Intel 也玩开卡升级?

- Jokin - Engadget 中国版
把高阶的 CPU 关掉一两个核心或功能,再打成低阶的 CPU 来卖在业界是很正常的事,最早是让有生产瑕疵的芯片还能「废物利用」,后来则是演变成达到量产规模的手段(可以全部都做高端的,再视需要关掉一些东西变低阶的). 在 AMD 的世界里「开核」已经是一个众所周知,主机板商竞相标榜的功能,但看起来 Intel 出的这招又更进了一步 -- 直接由 Intel 卖软件来对 CPU 进行「解锁」,让 CPU Level up.

Chromium 升级到 V17 版本

- 龍渊冭子 - cnBeta.COM
尽管Chrome和Chromium的版本号没有任何意义,但我们还是不得不提一句,Chromium已经升级到了V17版本. 另外,Chrome Beta分支for Windows/Mac OS X/Linux和Chrome Frame则升级到了15.0.874.100,主要新特性:.

Chrome Dev 升级到 16.0.912.0

- MessyCS - 谷奥——探寻谷歌的奥秘
Chrome Dev 分支 for Mac/Windows/Linux 和 Chrome Frame 升级到了 16.0.912.0,主要更新:. Javascript V8 引擎升级到 3.6.6.3. Native Client 和 Pepper 插件模块将允许游戏和其他程序在全屏模式下使用第一人称来控制并锁定光标.

iOS升级经验分享

- - 技术改变世界 创新驱动中国 - 《程序员》官网
作者认为,及时关注、快速反应、覆盖测试是面对iOS系统升级时最重要的三大原则,文中还详细分析了iCloud Storage和Automatic Reference Counting这两大iOS 5新特性. 2011年10月初,iOS 5正式发布,带来了大量新特性. 随之而来的是大量应用需要针对iOS 5系统进行升级适配.