服务器x64升级之luajit gc64
1. 背景
是的,2018年以前,我们的服务器是32位程序,超过4GB内存会挂。
这其中很大一部分原因是luajit 2.1版本前内存受限(原因见链接),一个vm只支持不超过2GB的内存(看下面的图里的编译选项,MAP_32BIT 只能1G,开了LJ_ALLOC_MMAP_PROBE能到2G, GC64往下看。。。 oh,no,写文档前一直以为MAP_32BIT是2G,没实践过,前面的链接也没仔细看),32位程序反而没这个限制。
另外一个原因是,够用。当然,发生内存泄漏的时候,总会心慌慌。
2018年我们开启了新项目,luajit 2.1分支从提交上看趋于稳定,是时候趁此机会往前走一步了。
2. 编译
直接用git上最新代码,不过得选对分支,默认master是2.0(我就这样掉了一下坑),看来一下今年以来的改动基本都是修修小bug,影响不大,应该是稳定了。
在Makefile里打开GC64选项,为了方便gdb,把调试符号给加上。
# Uncomment the next line to generate debug information:
CCDEBUG= -g
...
# Enable GC64 mode for x64.
XCFLAGS+= -DLUAJIT_ENABLE_GC64
编译,测试,不行,调。关键字mmap,找到这段代码。
宏隔开,三段,用“#error msg”编译,用的是LJ_ALLOC_MMAP_PROBE这段。把下面的宏定义取消,重新编译,就ok了。
(补充一下,仔细看上图,GC64可用多少内存?128TB,够用了,笔者在电信行业见过最大的core dump是46GB,漏着跑了一夜,太大了,mdb都没法加载,之后再也没用过这么大内存的机器了,哈哈哈)
到这里,就差不多了,我们新项目用着没问题。
3. 其他
3.1. lua文件编译的变化
luajit 2.1中lua和luac两个命令合一,都叫luajit,把之前的lua和luac改成软链。
Makefile(也是我弄的,设计挺轻巧的,改天开篇讲,7年前初始版)相应修改:
- $(PROJBASE)/lib/bin/luac -o $(DEST_OUTDIR)/{}.lc {}.lua
+ LUA_PATH=$(PROJBASE)/lib/bin/?.lua $(PROJBASE)/lib/bin/luac -O3 -bg {}.lua $(DEST_OUTDIR)/{}.lc
其他改asset版本号自己find + xargs + sed改一下,debug不用设,opt level默认3,lua内断点依然生效,没特别关注,项目跑了几个月,这块没出什么问题。倒是tcmalloc + libunwind出了些问题,下篇讲。