mrubyで標準のmalloc/freeじゃなく、アプリ側で用意したメモリアロケータを指定してみる。
mrubyの初期化をmrb_open()
じゃなくてmrb_open_allocf()
にして、引数にアロケータの関数とその関数に渡すユーザデータを与えて呼び出すことで、アプリ側でメモリ管理ができる。
アロケータは typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud);
という型の関数で、サイズが0なら解放、0より大きい場合ポインタがNULL
なら新規確保、NULL
じゃなければ以前確保していた領域をリサイズした結果のポインタを返すことで、アプリ側で任意のメモリ管理ができる。デフォルトだと以下の様なアロケータになっている。
// src/state.c |
注意として、p == NULL
かつsize == 0
で呼び出されることもあるようだ。この場合はなにもせずに単にNULL
を返せばよい、はず。
テストとしてmalloc/realloc/free/イミフの数を数えるアロケータを指定して、単純にmrb_load_string()
に空の文字列を与えたときそれぞれ何回呼ばれるかカウントしてみた。
$ ./custom_allocator_rb |
同様のことをLua 5.2.1で試したところ
$ ./custom_allocator_lua |
となり、mrubyが合計3489回に対しLuaが602回と、Luaのほうが呼び出し回数が少なかった。
また、最大のメモリ使用量はmrubyが185Kに対し、Luaは22Kだった。
テストのソース
|