【エスケープかいせき】

エスケープ解析 とは?

公開:
💡 このデータ、外の誰かにも見られる?を調べる

オブジェクトなどへの参照が、メソッドやスレッドの外へ届くかを調べるコンパイラの解析。メモリ割り当てや同期の省略などを判断する材料になる。

📌 このページのポイント
参照が外へ届くかを調べる メソッドの内側 一時オブジェクト 値だけで計算 外へ参照を渡す オブジェクト 共有の場所へ保存 解析は判断材料。必ずスタックへ移す処理ではない
左は局所的な利用の模式例。最適化の実施や配置先は、処理系と条件による。
ひよこ ひよこ
エスケープって、何が逃げるの?
ペンギン先生 ペンギン先生
オブジェクトへの参照が、調べている範囲の外へ届くことを指すよ。たとえばメソッド内で作ったオブジェクトを共有の場所へ保存すれば、外の処理も使える。コンパイラは参照の流れを追って、その可能性を調べるんだ。
ひよこ ひよこ
外に出ないと何がうれしいの?
ペンギン先生 ペンギン先生
局所的な計算にしか使わないなら、オブジェクトを丸ごと作らず、必要な値だけで計算できる場合があるよ。これがスカラー置換だね。ほかのスレッドと共有されないと確認できれば、不要な同期を省ける場合もあるんだ。
ひよこ ひよこ
つまりヒープからスタックへ移す仕組み?
ペンギン先生 ペンギン先生
それだけを意味する言葉ではないよ。解析は使われる範囲を調べることで、その後の最適化は処理系次第なんだ。OracleのJava SE 8向けHotSpot解説では、割り当て除去などを行い、非エスケープの割り当てをスタックへ置き換える方式ではないと説明しているよ。
ひよこ ひよこ
ローカル変数に入れておけば必ず省略される?
ペンギン先生 ペンギン先生
参照を引数や戻り値で渡した先も関係するし、ローカル変数というだけでは決まらないよ。逆に、インライン化して広い範囲を見れば最適化できることもある。コンパイラが安全性を確認できるか、対象の形が最適化に対応するかを含めて判断されるんだ。
もっと詳しく知りたい人へ

解析に合わせてコードを複雑にしたほうがよいですか?

まず読みやすい実装を保ち、実際の処理系と負荷で割り当て量などを測ります。JITでは実行時の情報や最適化の段階でも結果が変わるため、ソース上のnewの数だけでは実際の割り当て回数を断定できません。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「エスケープ解析」って出てきたら「参照の届く範囲を調べて、最適化の可否を判断する解析」と思えればだいたいOK!

参考資料

← 用語集にもどる