记一次Java 调用JNI 堆外内存泄漏排查

在一个风和日丽,艳阳高照的夜晚。像往常一样准备上线, 拉镜像,停服务,启动最版本的镜像。测试咔咔一顿功能测试。嗯~~很完美。收工回家!

第二天收到短信 某台机器上的服务掉线了。没太在意,因为就那一台,其他的机器都没问题。慢悠悠登上服务器,结果发现特么半天登不上去。心里咯噔一下!赶紧看其他机器,幸好其他机器等等上去。上去一看内存快爆掉了。赶紧联系加内存,没想到加完内存后没一会儿就又要满了。卧槽 事情大发了,赶紧给docker镜像设置内存,让它内存到了自动爆掉重启,不至于影响机器上其他服务。先这样将就一下(其实当时应该立马回退docker镜像的)。

然后到测试环境做压测(已经定位到功能了),果然一会儿内存就爆了,用JMI远程连上去看Java内存才用了几百兆,但docker镜像的内存上显示用了好几个G,猜测是堆外内存存在泄漏。于是乎pmap、jmap等命令一顿操作分析后发现并没有什么卵用,准备回退版本,用上个版本的代码重新打了镜像包,放到测试环境压测,特么没一会儿又爆了(哔了狗了)。

排查Java代码并无问题,JNI代码里面该回收的都回收了。C++代码单独压测并无问题。但是就是调用完JNI后内存一直增长。

抱着死马当作活马医的想法,把线上版本回退到上一个镜像后问题神奇的没有复现了。于是开始比较线上的镜像和我自己打包的那个镜像。里面的引用的jar包一毛一样。反编译该功能代码后也一毛一样。卧槽 啥情况~~~

docker inspect 镜像ID 查看两个镜像后发现里面用的JAVA_VERSION稍有不同

线上没问题的那个镜像:JAVA_VERSION=8u212-b04

自己重新打的镜像:JAVA_VERSION=8u252

使用的baseImage为docker.io/openjdk:8,沃日差一个小版本会这样?

于是指定baseImage为openjdk:8u212-b04后重新打个个版本测试发现问题不在了。

docker.io/openjdk:8此种方式默认使用jdk8的最新版本, 最新版本8u252应该存在bug,调用JNI时没有回收掉内存。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值