しかし、C# や Java などの言語には JIT コンパイラがあり、おそらくプラットフォーム ネイティブのマシン コードにコンパイルされます。
通訳者は、最終的に機械語に変換する必要もあります。しかし、JIT 担当者は、起動時間と実行時間を短縮するために、コンパイルと最適化に費やす労力を減らします。コンパイルに時間を浪費すると、ユーザーの観点から知覚されるパフォーマンスが低下するため、これはAoT コンパイラーのように 1 回だけ行う場合にのみ可能です。
また、コンパイル結果を監視して、ホット スポットをさらに再コンパイルおよび最適化するか、ほとんど使用されないパスを最適化解除する必要があります。そして、たまにGCを起動する必要があります。これらは、通常のコンパイル済みバイナリよりも時間がかかります。さらに、JITter と JITted プログラムのメモリ使用量が多いと、キャッシュの使用効率が低下し、パフォーマンスが低下する可能性があります。
メモリ使用量の詳細については、こちらを参照してください
次の理由により、Java のメモリ使用量は C++ のメモリ使用量よりもはるかに多くなります。
- Java では、オブジェクトごとに 8 バイト、配列ごとに 12 バイトのオーバーヘッドがあります (32 ビット。64 ビット Java では 2 倍)。オブジェクトのサイズが 8 バイトの倍数でない場合は、次の 8 の倍数に切り上げられます。これは、1 バイト フィールドを含むオブジェクトが 16 バイトを占有し、4 バイトの参照が必要であることを意味します。C++ は、仮想関数を宣言するすべてのオブジェクトにもポインター (通常は 4 または 8 バイト) を割り当てることに注意してください。
- Java ライブラリの一部は、プログラムの実行前にロードする必要があります (少なくとも、プログラムによって「フードの下で」使用されるクラス)。[60] これにより、小規模なアプリケーションのメモリ オーバーヘッドが大幅に増加します [要出典]。
- 通常、Java バイナリとネイティブの再コンパイルはどちらもメモリ内にあります。
- 仮想マシン自体が大量のメモリを消費します。
- Java では、複合オブジェクト (B と C のインスタンスを使用するクラス A) は、B と C の割り当てられたインスタンスへの参照を使用して作成されます。C++ では、これらのタイプの参照のメモリとパフォーマンスのコストは、B のインスタンスと/または C が A 内に存在する。
- アドレス演算の欠如により、狭い間隔の構造体や XOR リンク リストなど、メモリ効率の高いコンテナーを作成することができなくなります。
ほとんどの場合、C++ アプリケーションは、Java の仮想マシン、クラスのロード、および自動メモリ サイズ変更のオーバーヘッドが大きいため、同等の Java アプリケーションよりも少ないメモリを消費します。言語とランタイム環境を選択する際にメモリが重要な要素となるアプリケーションでは、費用対効果の分析が必要です。
また、ガベージ コレクタを使用するプログラムは、明示的なメモリ管理を使用するプログラムと同じパフォーマンスを達成するために、5 倍ものメモリを必要とする可能性があることにも注意してください。