Unity:WebGLでメモリエラーに苦しんだ話


はじめに

こんにちは、のんびりエンジニアのたっつーです。
ブログ運営しているのでぜひ興味あればご覧ください。

Unity のWebGLプラットフォームでのメモリエラーについてだいぶ悩まされたので、このエラーの解決方法を共有させていただきます。

具体的なエラーの内容

エラー1

「memory access out of bounds」のエラーが表示されて、Javascript から SendMessage を使用して Unity 側の関数呼び出しがエラーになって動かない場合。

Invoking error handler due to
Uncaught RuntimeError: memory access out of bounds
Uncaught RuntimeError: memory access out of bounds
    at wasm-function[8336]:324
    at wasm-function[8331]:257
    at wasm-function[1315]:929
    at wasm-function[1391]:124
    at wasm-function[6601]:898
    at wasm-function[6598]:117
    at wasm-function[8314]:478
    at wasm-function[26579]:17
    at Object.dynCall_iiii (blob:http://127.0.0.1:8887/df084535-121f-44bd-9351-339a7a3e5c5c:2:422103)
    at Object.handlerFunc (blob:http://127.0.0.1:8887/df084535-121f-44bd-9351-339a7a3e5c5c:2:208347)
    at jsEventHandler (blob:http://127.0.0.1:8887/df084535-121f-44bd-9351-339a7a3e5c5c:2:204833)

エラー2

Unityのビルド設定で「Development Build」にチェックが付いているとこのエラーが表示されます。

Stack overflow! Attempted to allocate 5242881 bytes on the stack, but stack has only 5242721 bytes available!
Invoking error handler due to
Uncaught abort("Stack overflow! Attempted to allocate 5242881 bytes on the stack, but stack has only 5242721 bytes available!") at Error
    at jsStackTrace (App.wasm.framework.unityweb:693:12)
    at stackTrace [Object.stackTrace] (App.wasm.framework.unityweb:707:11)
    at Object.onAbort (http://127.0.0.1:8887/Build/UnityLoader.js:1039:50)
    at abort (App.wasm.framework.unityweb:25388:20)
    at abortStackOverflow (App.wasm.framework.unityweb:752:2)
    at stackAlloc (wasm-function[590]:33)
    at blob:http://127.0.0.1:8887/cd9afda3-5ef3-4581-837c-a22f63982caa:24136:37
    at stringToC (App.wasm.framework.unityweb:368:10)
    at ccall [Object.ccall] (App.wasm.framework.unityweb:388:16)
    at SendMessage [Object.SendMessage] (App.wasm.framework.unityweb:72:151)
    at Object.SendMessage (http://127.0.0.1:8887/Build/UnityLoader.js:1057:50)
    at http://127.0.0.1:8887/:19:22

対策方法

インスタンスを生成する際に「Module: { TOTAL_STACK: 6 * 1024 * 1024 }」を指定しましょう、次は正常に動作しましたね!

ちなみにですが、 TOTAL_MEMORY / TOTAL_STACK の2つの領域を調整する事を推奨します。
メモリの指定サイズは、TOTAL_MEMORY > TOTAL_STACK になるように指定します。

    <script>
      var gameInstance = UnityLoader.instantiate(
                            "gameContainer", 
                            "Build/App.json", 
                             {
                               onProgress: UnityProgress, 
                               Module: { TOTAL_STACK: 6 * 1024 * 1024 }
                             });

      setInterval(function() {
        var text = "";
        for(var i = 0; i < 5*1024*1024 / 4; i++) {
          text += "*";
        }
        gameInstance.SendMessage('MyGameObject', 'MyFunction', text);
      }, 1000);
    </script>

その他

再現するソースコード、適当な解説、解決するために読んだ資料等 は、ブログ「Unity:WebGLでメモリエラーに苦しんだ話」 に記載しておりますので、気になる方はぜひご参照ください。