Java 8 の非決定的なスタック深さ
Java の最大再帰深さを決定することは、スタック使用率と潜在的なメモリ問題を理解するために重要です。 。ただし、Oracle の Java 8 では、報告される結果が非決定的になる可能性がありますが、対照的に、OpenJDK 7 では一貫した結果が得られます。
HotSpot Optimizer の影響
HotSpot コンパイラ オプティマイザーは、観察される動作に大きな影響を与えます。再帰メソッドが JIT コンパイルされる場合、オプティマイザーは特定のメソッド呼び出しを最適化したり、複数の呼び出しのスタック フレームをマージしたりすることがあります。この最適化により、必要なスタック領域が小さくなり、より深い再帰が可能になります。
例
次のコードを考えてみましょう:
<code class="java">public static int countDepth() { try { return 1+countDepth(); } catch(StackOverflowError err) { return 0; } }</code>
JIT を使用した結果 (Oracle の Java 8 から):
2097 4195 4195 4195 12587 12587 12587
JIT を使用しない結果 (Oracle の Java 8 から):
2104 2104 2104 2104 2104 2104 2104
スタック制限の強制と ASLR
非決定性に影響を与えるもう 1 つの要因は、JVM がスタック制限を強制する方法です。スタック終了アドレスに特別な位置合わせが必要な場合 (ハードウェア制限によるページ境界への位置合わせなど)、初期スタック割り当ての位置合わせ制約が弱くなる場合があります。アドレス空間レイアウトのランダム化 (ASLR) と組み合わせると、使用可能なスタック領域の量が変化し、再帰の深さが非決定的になる可能性があります。
OpenJDK 7 の決定性
Oracle の Java 8 とは対照的に、OpenJDK 7 はスタック制限をより一貫して適用しているようで、デフォルトでは ASLR を適用しません。これは、OpenJDK 7 で観察される決定論的な動作を説明しています。
以上がJava 8 では再帰の深さが非決定的であるのに、OpenJDK 7 では決定的であるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。