你好,春哥
我们的系统使用了nginx的lua模块,通过luajit的ffi来调用一个c库的一个接口对数据做一些处理,然后再返回给前端。目前在线上发现系统运行很长时间之后偶尔会有个别nginx进程出现内存占用很大的情况,在error log中报以下错误:
failed to load external Lua file: memory allocation error
我通过nginx-gdb-utils的lgcstat调试了一下,发现luajit使用的内存已达1GB上限,具体如下:
(gdb) lgcstat
28901 str objects: max=2790981, avg = 15668, min=18, sum=452825982
8472 upval objects: max=24, avg = 24, min=24, sum=203328
2070 thread objects: max=2464, avg = 2462, min=568, sum=5096952
119 proto objects: max=3284, avg = 436, min=92, sum=51894
85462 func objects: max=144, avg = 27, min=20, sum=2320504
63 trace objects: max=2076, avg = 499, min=160, sum=31444
44970 cdata objects: max=600, avg = 39, min=12, sum=1764100
34766 tab objects: max=6176, avg = 121, min=32, sum=4236000
114826 udata objects: max=528396, avg = 5144, min=27, sum=590741282
sizeof strhash 131072
sizeof g->tmpbuf 0
sizeof ctype_state 4568
sizeof jit_state 6024
total sz 1057418310
g->strnum 28901, g->gc.total 1060209274
从结果看来userdata和str占用空间最多,分别占用了590MB和452MB(这里tmpbuf的大小为0是因为我这里使用的时候会报一个找不到成员e的错误,因此我把tmpbuf相关的代码注释掉了)。请问一下接下来有什么思路可以继续追查下去。
以下是我们的简化后的相关代码,麻烦看下是不是使用上有什么问题:
我们调用的这个接口是这样的:
typedef struct
{
int a;
char b[256];
...
} foo;
int func(const void *in_data, const size_t in_data_len, foo *f, void **out_data, size_t *out_data_len);
我们是这样调用的:
local foo = ffi.new("foo[1]")
foo[0].a = ...;
foo[1].b = ...;
local in_data = ...;
local in_data_len = ...;
local out_data = ffi.new("void*[1]")
local out_data_len = ffi.new("size_t[1]", 0)
local ret = lib.func(in_data, in_data_len, foo, out_data, out_data_len)
local final_data = ffi.string(out_data[0], out_data_len[0])
ffi.C.free(out_data[0])
我们使用的是luajit2.0.3
谢谢!