使用thrift,每隔一段时间就会报错:java.lang.OutOfMemoryError: Direct buffer memory

背景:使用thrif(版本0.9.3)对外提供服务,每隔一段时间thrif服务就挂掉。

问题定位过程

1、查看日志,发现存在java.lang.OutOfMemoryError: Direct buffer memory异常,因为thrif用到nio,发现启动服务没有配置直接内存,想当然认为是直接内存过小,于是在jvm启动参数加大了直接内存的最大值(-XX:MaxDirectMemorySize),后续观察。过了一段时间,问题还是复现了。

2、再查日志还是报直接内存溢出,然后再仔细查看日志,发现直接内存溢出时,thrif尝试去解析一个(1个G多)字节数组,为什么会有这么大的对象,thrif都是用定义好的可序列话的对象,后发现向thrif监听的端口发送http请求(直接在浏览器地址栏输入http://ip:port/),就会复现解析大的字节数组,原来thrif用的是可序列话定义好的对象,而发送http请求的话,thrif无法解析http报文,解析出错造成直接内存区生成一个很大的字节数组,造成直接内存溢出。

解决:

1、直接修改thrift源码,设置单个请求报文最大值(修改AbstractNonblockingServer类的MAX_READ_BUFFER_BYTES属性,这个属性是long类型的最大值,相当于1045576TB,这等于没有限制),根据自己的业务场景来修改最大值。

2、也可以升级thrif的版本,高版本已解决这个问题(例:0.12.0 )。

验证:

再次向thrif服务发送http请求,该异常会被程序catch掉,提示

ERROR:Read a frame size of 1295726556, which is bigger than the maximum allowable buffer size for ALL connections.。

不会耗尽直接内存而造成内存溢出了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值