--:-- LUA API

実行時間とメモリの上限

終わらないループの打ち切りと、1アプリが使えるメモリ

実行時間の上限(命令数)

Luaのコールバック(loop(dt) やイベント)の中に終わらないループがあると、OS全体が止まってしまいます。そうならないよう、1回の呼び出しで実行できるLuaの命令数に上限(200万命令)があります。

while true do end  -- 上限に達するとエラーとして打ち切られる
  • 数えるのは、トップレベルの実行・setup()・loop()・各イベント・HTTPやタイマーのコールバックなど、OSから呼ばれる1回ごとです。
  • 上限に達するとエラーダイアログが出ます。loop() で起きたときは、それ以降 loop() は呼ばれなくなります。
  • 時間ではなく命令数で数えます。pico.sd_read() のようなOSの関数の中で待っている時間は数えません。
  • 重い計算を1フレームでやりきろうとすると引っかかることがあります。何フレームかに分けてください。

pcall では止められない

上限に達した呼び出しは、pcall / xpcall / コルーチンで捕まえても、最後まで打ち切られます。次にOSから呼ばれたとき(次の loop() や次のイベント)にまた動けるようになります。

それでも止まらないもの

とても重い string.find のパターンのように、Luaの命令ではなくOSの関数の中で時間がかかるものは数えられません。設定アプリの「固まったら再起動する」を入れておくと、固まったときに再起動します。

メモリの上限

1つのアプリのLuaが使えるメモリは 200KB までです。スクリプトのコード、テーブル、文字列など、Luaが確保するもの全部が入ります。

  • 超えると、Luaの「メモリ不足」(not enough memory)のエラーになります。OSは落ちません。
  • ウィジェットと画像(pico.image_load)はこの200KBとは別に数えます(画像は8枚・96KiBまで)。
  • 今の使用量は pico.memory_info() で分かります。
  • 大きなJSONを丸ごと pico.json_decode すると一気に使います。数個の値だけなら pico.json_pick を使ってください。
  • コードが大きいアプリは、app.cfg の strip_debug=true でモジュールの大きさを減らせます(モジュール)。

つまずいたときに疑う場所

症状疑うところ
エラーダイアログが出て loop() が止まった命令数の上限、またはスクリプトのバグ(ダイアログのスタックトレースを見る)
pico.sd_read() が nilファイルが16KiBより大きい、ファイルが無い、権限(アプリのフォルダの外)
pico.image_load() が nil枚数(8枚)・合計(96KiB)の上限、形式(プログレッシブJPEG等)、権限
pico.http_request() が falsepermission_network が無い、順番待ちがいっぱい、URLが不正、送る本文が16KiBより大きい
not enough memoryLuaのメモリ(200KB)を使い切った

上限の一覧は 上限 にあります。