系统协议:
架构在UDP协议上的MQTT协议。
内存溢出可能出现的情况:
1. 假设仅在接收客户端报文的时候会申请堆外内存,每个报文为1KB,程序最大的堆外内存为512MB,那么最大支持524288个客户端同时发包,超出可能会导致OOM。
2. 假设程序最大的Direct Memory(可由-XX:MaxDirectMemorySize参数决定)为512MB,此时程序已用的堆外内存为100MB,操作系统仅剩下101MB,那么在这部分已使用的堆外内存没释放之前,去申请新的内存有可能会发生OOM。
3. 程序使用了Direct Memory,但是没有释放。
排查过程
一、问题定位
根据上图的堆栈信息可以看出,程序在申请16777216个字节的堆外内存时报错。结合系统此时的客户端连接数(几百个),可以得知,基本为程序的BUG(申请了堆外内存但是没有成功释放)
二、尝试解决
Review了一遍代码,定位到有一处代码:
ByteBuf b = buffer.readRetainedSlice(bytesRemainingInVariablePart);
分析了readRetainedSilice方法的源