それらの両方はほとんど同じことをします。メソッドがホットであることを識別し、解釈する代わりにコンパイルします。 OSRでは、メソッドが2回呼び出されたときにコンパイルされたコードが呼び出されるJITとは異なり、コンパイルされた直後にコンパイルされたバージョンに移動します。
これ以外に違いはありますか?
一般に、Just-in-timeコンパイルとは、実行時にネイティブコードをコンパイルし、解釈する代わりに(またはそれに加えて)実行することを指します。 Google V8などの一部のVMには、インタプリタすらありません。それらは、実行されるすべての関数を(さまざまな程度の最適化で)JITコンパイルします。
オンスタック置換(OSR)は、同じ機能の異なる実装を切り替えるための手法です。たとえば、OSRを使用して、コンパイルが完了するとすぐに、インタープリター型または最適化されていないコードからJITコードに切り替えることができます。
OSRは、実行中に関数を「ホット」として識別する状況で役立ちます。これは、関数が頻繁に呼び出されるためとは限りません。一度だけ呼び出される場合もありますが、最適化の恩恵を受ける可能性のある大きなループで多くの時間を費やします。 OSRが発生すると、VMが一時停止され、ターゲット関数のスタックフレームが、異なる場所に変数を持つ可能性のある同等のフレームに置き換えられます。
OSRは、最適化されたコードから最適化されていないコードまたはインタープリター型コードへの逆方向にも発生する可能性があります。最適化されたコードは、過去の動作に基づいて、プログラムの実行時の動作についていくつかの仮定を行う場合があります。たとえば、1つのタイプのレシーバーオブジェクトしか見たことがない場合は、仮想メソッド呼び出しまたは動的メソッド呼び出しを静的呼び出しに変換できます。後でこれらの仮定が間違っていたことが判明した場合、OSRを使用して、より保守的な実装にフォールバックできます。最適化されたスタックフレームは、最適化されていないスタックフレームに変換されます。 VMがインライン化をサポートしている場合、最適化されたスタックフレームをいくつか最適化されていないスタックフレームに変換することになる可能性もあります。
はい、それはほとんどそれです。 ジャストインタイムコンパイル バイトコードの「ホットスポット」(非常に頻繁に実行されることがわかっている/想定されるバイトコードのスポット)をネイティブ命令にコンパイルすることにより、パフォーマンスを向上させることができます。 スタック上の置換 長時間実行される解釈された「ホット」バイトコードが利用可能になったときにコンパイルされたバージョンに置き換えることにより、JIT機能を補完します。言及された オンスタック置換の記事 は、JITコンパイルがOSRなしではあまり役に立たないという良い例を示しています。