Skip to content
cloudwu edited this page Nov 27, 2014 · 5 revisions

skynet 修改了 Lua 的官方实现(可选),加入了一个新特性,可以让多个 Lua VM 共享相同的函数原型1。当在同一个 skynet 进程中开启了大量 lua VM 时,这个特性可以节省不少内存,且提高了 VM 启动速度。

这个特性的使用,对一般用户来说是透明的。它改写了 lua 的辅助 API luaL_loadfilex ,所有直接或间接调用这个 api 都会受其影响。比如:loadfile 、require 等。它以文件名做 key ,一旦检索到之前有加载过相同文件名的 lua 文件,则从内存中找到之前的函数原型替代。注:Lua 函数是由函数原型以及 0 或多个 upvalue 绑定而成。

loadstring 不受其影响。所以,如果你需要多次加载一份 lua 文件,可以使用 io.open 打开文件,并使用 load 加载。

代码缓存采用只增加不删除的策略,也就是说,一旦你加载过一份脚本,那么到进程结束前,它占据的内存永远不会释放(也不会被加载多次)。在大多数情况下,这不会有问题。

skynet 留出了接口清理缓存,以便于做类似热更新的工作。接口模块叫做 skynet.codecache 。

local cache = require "skynet.codecache"
cache.clear()

这样就可以清理掉代码缓存。这个 api 是线程安全的,且老版本的数据依旧在内存中(可能被引用)。但需注意,单纯靠清理缓存的方式做热更新的方案是不完备的。这个完备性和是否引入这个特性无关。因为当你的系统在加载一批 lua 脚本时,单靠源文件的更新,无法保证这批脚本加载的原子性。(有部分是旧版本的,有部分是新版本的)