mbed-mruby で mruby がとってるヒープサイズを調べた
GR-PEACHはデフォルトのヒープサイズを512Kしかとってません(RAMは10Mあるのに。mbed-srcいちいち直すのはめんどい)。最近はmbed(GR-PEACH)にmrubyを乗せて遊んでいますが、mrubyでThreadを作ると、2個めのThreadでもうヒープ枯渇します。これは現状Thread作るたびに、VMをコピーしてるので、それが大きいんだと思います。
そこで、mrubyでどのくらいヒープを使うのか調べてみました。
調べた方法
gc.cのmrb_malloc()関連は、結局mrb_realloc_simple()を呼んでいます。で、mrb_realloc_simple()は、allocfを指定していない限りは、state.cのmrb_default_allocf()を呼んで確保も解放もしています。ここでrealloc()とfree()を自前の関数に置き換えてサイズを記録しました。
そして、ユーザボタン割り込みで下のログを出力します。
sizeは現在の使用量、acntはallocが呼ばれた回数、fcntはfreeが呼ばれた回数、maxは最大使用量。
================================================== size = XXX, acnt = XXX, fcnt = XXX, max = XXX ==================================================
結果
mirb - Embeddable Interactive Ruby Shell > ================================================== size = 175736, acnt = 2236, fcnt = 252, max = 181627 ================================================== > a = DigitalOut.new LED1 => #<DigitalOut:0x200b3498> > ================================================== size = 189478, acnt = 2279, fcnt = 269, max = 237908 ================================================== > b = Ticker.new => #<Ticker:0x200b3288> > b.attach(1, a) do |led| * led.toggle * end => #<Ticker:0x200b3288> > ================================================== size = 406359, acnt = 4619, fcnt = 554, max = 422416 ================================================== > b.detach => #<Ticker:0x200b3288> > ================================================== size = 263790, acnt = 4663, fcnt = 2544, max = 468548 ================================================== > b = nil => nil > ================================================== size = 270089, acnt = 4684, fcnt = 2553, max = 468548 ================================================== => nil > ================================================== size = 276380, acnt = 4705, fcnt = 2562, max = 468548 ================================================== => nil > ================================================== size = 282671, acnt = 4726, fcnt = 2571, max = 468548 ==================================================
mirbを起動した時点 176K
DigitalOut.new した 189K
Tickerアタッチした(Threadを作った) 406K
Tickerデタッチした(Threadを破棄した) 264K
そして、Enterするたびに 10K づつぐらい増えてる。なんで。
VM一個あたりやはり200K近く消費するようです。ちなみにgemboxはdefaultで、加えてmbed用のgemを入れています。gemを削ればもう少し楽になるかもしれません。
ともかく、こんなペースでメモリを食うと、とてもじゃないけど使い物にならない。かと言ってスレッド使えないとかは無しだと思うので、やり方を考えないといけません。