Hello!
On Tue, May 6, 2014 at 2:14 AM, Harold.Miao wrote:
> 设置一块share_dict, 然后以64个缓冲区形式的key, key的值(args['data'])在高速刷新 , key的值大约4k左右。
>
ngx_lua 模块的 shared dict API 使用的是 NGINX 核心中的 slab allocator 来管理内存的,而这个
slab allocator 对于大于页大小(4k)的块存在较严重的内存碎片问题。
建议给你的 nginx 核心打上下面这个补丁:
https://raw.githubusercontent.com/openresty/ngx_openresty/master/patches/nginx-1.7.0-slab_defrag.patch
该补丁(或其变种)将会直接包含在下一个 openresty 发布中。
针对此问题我准备了一系列测试用例:https://github.com/openresty/lua-nginx-module/blob/master/t/126-shdict-frag.t#L22
在 nginx 带有上面的补丁时,这些用例现在都通过了。
注意,Monkey Zhang 给出的那个 nginx-devel 邮件列表讨论里由 Wandenberg Peixoto
给出的补丁在一些极端情况下会有一些问题,比如潜在的深递归调用导致 C
栈溢出,以及在分配失败时较为集中的块合并操作可能会导致程序暂停较长时间,所以并不推荐。
我的补丁在每次释放 pages
时对前后位置上的空闲块都立即进行合并(如果有的话),所以合并开销可以均匀地散布开来。当然我的补丁有一个缺点是元信息的空间会略大一点(对于超过半页大小的块在
64 位系统上会多 8 个字节的元数据,而对于小于半页大小的块则每一页会多使用 8 个字节)。
Regards,
-agentzh