内存问题 #323

Closed
yibiaochen opened this Issue Aug 11, 2015 · 12 comments

Projects

None yet

3 participants

@yibiaochen
Contributor

我们一个玩家一个agent,将玩家踢下线关掉agent之后,发现dump_c_mem出来的结果,C层面还有一定的内存没有被销毁,数额不等,大概从200k~1,2M的样子,运行越久未被释放的越多。没有自己写的C服务,全部是lua服务,除了用pbc来跟客户端交互。有人遇到同样的问题么?云风有啥建议查证一下不:-D
ps:跟在ejoy的旧同事交流过,他的测试结果也是有一定残余

@cloudwu
Owner
cloudwu commented Aug 11, 2015

最好能确认没有销毁的内存到底是什么。

能确定的是:lua 代码本身是不会释放的。但同一份文件只会有一份在内存。

@cloudwu
Owner
cloudwu commented Aug 11, 2015

我测试了 skynet 目前自带的例子,除了第一次连上去退出后 agent 会遗留内存外,以后再连接的都不会,符合上面我说的结论。

具体你的问题你想查,可以打开 jemalloc 的内存泄露分析,或自己修改 malloc_hook 加入更多信息用来推断没有释放的到底是什么。

@linxiaolong

我这边情况测了下如下:
2015-08-11 15 11 00
如图 0000001a 00000022 00000024 均为已经杀掉的agent,0000001a是第一个启动的agent,因为有codecache持续留着很正常,后面两个最后都留下64B,也没继续增长

@cloudwu
Owner
cloudwu commented Aug 11, 2015

肯定是你有 C 代码分配了内存没有释放。建议用如下方法排查:

修改 malloc_hook.c , 在 malloc/free/realloc/calloc 等 skynet 定制版本的函数中加上 log, 把调用信息写到 log 文件中。注意,这里可以拿到是从哪个服务分配出来的,你需要按服务分别 log 到不同文件,方便分析。注:这里可以和 cmemory 采用同样的手法,建一个 64K 静态数组保存 log FILE * ,或直接查入 cmemory 的记录中去。

把最后那个供 lua 使用的分配器中的内存管理调用,绕开上面的函数避免不必要的 log 。因为你要相信 lua vm 一定在内存管理上是绝对干净的。

做此修改后, 你再跑测试, 应该会生成很多 log 文件。 然后写一个脚本分析 log ,看一下有哪些内存块没有释放。由于以上修改排除了 lua vm 的内存操作,所以剩下的应该非常少,或许不用写脚本,人肉就可以得到结论。

一旦发现没有释放的,再进一步推测是哪里的问题。(可以根据长度,或用别的手段)

@yibiaochen
Contributor

嗯,感谢云风,我先按你的方法看看

@cloudwu
Owner
cloudwu commented Aug 11, 2015

我想起来,这个方法有点问题。 因为你不能在 malloc hook 里调用文件 api (比如 fopen), 因为它本身会调用 malloc 。就递归了。

所以你需要在进入 malloc hook 时加一个TLS 变量做标记,避免重入。

@cloudwu
Owner
cloudwu commented Aug 12, 2015

我找到问题了, 但是撞鬼了. 今天我这个 bugfix 提交并不是今天修正的. 我的机器上的本地代码里一直有这一行代码. 但是 git 仓库里没有. 并且, 我用 git status 和 git diff 都看不到差异.

这行代码从头到尾都在我的本地机器里. 重新 clone 了一份, 然后才把这行代码修改提交了.

完全不明白 :(

@cloudwu
Owner
cloudwu commented Aug 12, 2015

所以我自己机器上一直都发现不了问题. 今天在同事机器上找到的.

@cloudwu
Owner
cloudwu commented Aug 12, 2015

ps. 需要 make cleanall 才会重新编译 lua

@yibiaochen
Contributor

我合了最新的skynet代码,发现这一行一直是有的(上一次合并是4月份,大概是出了1.0版本出了后不久)。我估计还是我们哪里引起的泄露,我继续查。。

@cloudwu
Owner
cloudwu commented Aug 14, 2015

这个库和 skynet 带的 skynet.pack skynet.unpack 没有差别. 但后来没有维护.

@linxiaolong linxiaolong pushed a commit to pigparadise/skynet that referenced this issue Aug 14, 2015
@cloudwu + davidlin bugfix: memory leak , See Issue #323 e587bb5
@yibiaochen yibiaochen closed this Aug 15, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment