场景:
100个并发线程同时发出100个请求,请求中涉及redis的set,get,expire操作,操作的key value大小为1M,设置最大堆外内存为100M
分析:
在测试过程中,发现io.netty.util.internal.PlatformDependent#DIRECT_MEMORY_COUNTER的值在高并发下突然变多。检查内存使用过程,发现flush的地方存在释放bytebuffer的逻辑,所以猜测是flush的环节有问题。经过debug发现,在flush的时候直接返回了(红框处)。原因是因为socket缓冲区不够用了,所以没有真正的flush掉,相应的bytebuffer也没有释放掉,造成内存溢出
原因:
sokect满了导致无法真正的flush,所以堆外的数据会被缓存,没能释放掉。如果调整SO_SENDBUFF可以有一定改善。但本次问题的场景在于,最好不要使用大key。