Mina SftpFileSystem fullgc 内存泄露

问题描述:

生产环境运行一段时间后,节点服务均频繁发生full gc,最多的一天将近百次,full gc的时间也越来越长,有内存泄露的可能。

原因分析:

服务使用Mina的SftpFileSystem进行文件处理,其中引用的一个SftpClient对象使用了链式编程,对象使用后没有进行关闭,无法被回收,导致应用线程占用的内存越来越大,fullgc可回收的内存越来越少,最终会导致内存泄露,应用宕机。

Iterable<SftpClient.DirEntry> dirEntries = sftpFileSystem.getClient().listDir(handle)

感觉还是编码习惯问题,该写法并没有逻辑问题,只是不容易发现需要关闭的对象。

该问题与github上apache mina-ssdh版本2.9.x及以下源码存在的一个SftpClient对象内存泄露问题相似,官方已在2.10.x及以上版本修复,2.9.x版本内存泄露源码如下:

堆栈信息:

解决方法:

1、非链式编程,SftpClient对象使用局部变量定义,这样就容易看出对象是否需要关闭

 SftpClient sftpClient = sftpFileSystem.getClient();  

 sftpClient.listDir(handle)

2、在finally代码块中调用其close方法进行关闭
if (null != sftpClient) {

sftpClient.close();

}

反思与总结:

1、手动或使用try-resources关闭资源型对象

      使用Mina进行SFTP连接处理文件过程中,要及时对相关资源对象进行手动关闭或使用try-resources自动关闭,防止出现内存泄露。对于此次问题,常用但不限于以下对象:

1、SftpFileSystem
2、ClientSession
3、SshClient
4、SftpClient

2、资源性对象,尽量不要使用链式编程

      在开发过程中,有时为了编码方便,对于复合性对象属性的获取,大多会使用链式编程,但对于资源对象,如果使用链式编程,可能会忘记对象的关闭,导致资源对象无法回收,从而导致内存泄露。

链式编程(不推荐):sftpFileSystem.getClient().listDir(handle)

非链式编程(推荐):SftpClient sftpClient = sftpFileSystem.getClient();
                 sftpClient.listDir(handle);

详情请参考Github:

https://github.com/apache/mina-sshd/issues/294

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值