Hello!
2013/12/17 petzold
>
> 我们在使用openresty的时候遇到了一些问题,在luajit的内存占用较多时,会出现如下图的coredump:
>
> lua占用的内存已经接近了1G,之后我们谷歌了下,发现您之前在github上回答该问题的url:
应当避免单个 worker 里的 Lua VM 的内存使用接近 1GB. 毕竟 LuaJIT 目前的 GC
实现不足以在这种量级的内存使用量下保持足够高的性能。你在 Lua 空间内存储了什么数据能达到这种规模?
当然,更常见的一种情形是你的 Lua 代码本身存在内存泄漏。
值得一提的是,较老版本的 ngx_lua 模块存在已经修复了的内存泄漏问题。建议你使用最新的 0.9.3 版(如果你直接使用的是
ngx_openresty 软件,可以直接升级到最新的主线版 1.4.3.9)。
你可以使用 ngx-lj-gc-objs 工具对你某一个内存占用很大的 nginx worker 进程里的 Lua GC 内存分配情况进行实时分析:
https://github.com/agentzh/stapxx#ngx-lj-gc-objs
这样有助于分析你的 Lua 代码具体的内存使用情况。
> 尝试过-fPIC编译后,我们发现还是没有能够解决问题,所以我们有几个问题咨询下:
>
这个选项只有当 C 空间内在低 2G 地址空间里分配了很多内存时才有意义。
> 1. luajit使用了mmap,并且使用了MAP_32BIT标识,但是根据man的描述:
> MAP_32BIT (since Linux 2.4.20, 2.6)
> Put the mapping into the first 2 Gigabytes of the process address space. This flag is only supported on x86-64, for 64-bit pro-
> 应该是可以使用2GB内存的,为啥我们这边1GB左右就挂了
虽然 man 如是说,但 Linux 内核的实现其实一直都是在 1GB 的地址空间内搜索空闲块的。
>
> 2. 应该怎样解决这个问题?是应该使用collectgarbage来定期回收内存吗?如果这样的话,会不会对系统的稳定性有一些损害
>
你首先需要确认究竟是因为 LuaJIT GC 来不及回收块呢,还是因为你的 Lua 代码存在内存泄漏。
如果是前者,你可以尝试避免过快地分配过多的 Lua 对象(毕竟 Lua 世界不像 Java 世界那样认为疯狂地创建新对象是完全正常的玩法)。
如果是后者,你可以通过 ngx-lj-gc-objs 这样的工具对泄漏的位置进行追踪。
Best regards,
-agentzh