一个socket服务网项目,每台机器的线程量3w左右。最后一次更新发布后,出现了一个奇怪的问题,就是运行一段时间之后,jvm的堆外内存就会基本被占用完,需要重启一次服务器才行。为了服务器安全,设置了一个内存使用上限比例,当服务器内存使用比例到达这个数值之后,就不再接收用户的请求,表现出来的现象就是用户无法登陆了。问题很严重。
经过几位高级工程师的讨论和分析,猜测造成这种现象可能的原因有两个:
1.我们的应用中使用了ByteBuffer.allocateDirect ,这种方式会使用堆外内存,但由于线上服务器使用的jdk版本时 6.32之前的一个版本,在此之前的版本中存在堆外内存回收的bug,因此认为可能是这个原因导致了当前问题。
2.jdk工具包中的java.util.zip.Deflater方法会使用堆外内存,同时,这个方法还存在内存释放方面的bug。我们的应用中使用了xmpp,据说这个会很频繁的调用这个方法,有可能是这个原因造成的服务器堆外内存溢出 。
但是堆外内存很难检测,按照文章中的推荐,需要使用工具查看我们的应用中是否有不停的调用这个方法,推荐的工具是google-perftools。这个东西还没怎么用过,需要了解一下怎么安装和使用。尽快把环境部署起来吧。
近期评论