最近用nodejs+socket.io(socket版本1.7.2)做了一个手游的服务端,最近这几天做小规模的线上测试的时候发现有内测泄露的问题(内存有减少,但减少的速度远远小于增长的速度),同时CPU也在不断的增长
具体表现就是大概100多人同时在在线的时候大概5个小时左右内存就到了1G了(服务器是双核4G的配置,只跑了这一个进程),这个是用PM2看loop delay 到了20ms的样子, 大概内存涨到1.5G的时候,已经明显感觉到游戏里面各种卡、延迟。所以现在临时解决方案是内存到了1G的时候重启一下node进程
服务端这边没有任何密集型的运算,就只用socket做了一些数据的转发(即一个客户端发上来数据,我再把这个数据广播给其他人),广播的数量也不是很大,一般也最多6个人 socket这边用户连上来的时候我把用户的一些数据保存在内存里,同时把当前用户的socket的对象也保存在内存里,当用户断开连接的时候删除前面保存的数据 用户从连上到断开一般在3分钟左右的时间(因为一局游戏时长是3分钟)
1.怀疑是不是TCP连接未释放的问题,但是在测试中发现新上来一个连接和断开之后,在Linux服务器上看到对应端口的连接数是有相应的变化的 2.因为游戏中有很多和时间相关的东西,所以用到了node-schedule这个库,怀疑是不是这个库造成的 但是我在代码里每次创建一个task的时候我都赋值给一个变量,当task执行后我都是先cancel然后在delete这个变量(逻辑上应该没问题)
对这块比较小白,还请给为老司机给点建议,如何下手
@hyj1991 谢谢
持续关注下 从描述目前看不出什么问题来
打个heapdump 吧,否则一切都是空谈。不过目前来看,肯定不是与socket.io和tcp有关,大概率是定时任务执行后有些变量未释放导致
@royalrover 嗯,因为现在有真实用户在,所以线上的代码不好改。 我在测试环境打过几个heapdump,不过看不懂啊,请问有如何看heapdump这方面的资料吗?
文件通过chrome打开,分析几个不同时间段的dump文件,找找有没有一直存在的对象,这往往就是内存泄漏的根源
@royalrover 好的。谢谢
@imhered 你在测试环境用ab或者写个连续上下线用例,看着点内存,足够大后heapdump出来,导入到chrome后,你可以按Object数排序,选中之后看对应下面那栏有引用堆栈。另外可以留意下有没有过大的distance。具体你看自己Google吧~
另,我觉得解决顺序应该是 dump出内存->分析假设->验证
。而不是猜想->验证
。你内存很容就爆,那犯罪现场就在内存里,dump出来导入chrome查问题。用chrome的profiler确实不太好一眼看出问题,但很大几率给你重要线索。
另另,正因为profiler不好用。。才有alinode
,哈哈,内存和gc一目了然
mark 等结果
来自酷炫的 CNodeMD
heapdump用chrome可以看,webstorm也可以,可以看看哪些对象占用了大量的内存 基本可以确定泄露在哪里的 heap snapshot 博客一篇
瞧瞧呢~