web-dev-qa-db-ja.com

V8のスタックとヒープ(JavaScript)

v8はJVMのようにスタックとヒープを使用しますか?もしそうなら、それはスタックにプリミティブを置き、ヒープにオブジェクトを置きますか?

30
user815070

はい、V8はJVMや他のほとんどの言語と同様のヒープを使用します。ただし、これは、ローカル変数(原則として)がスタックに配置され、オブジェクトがヒープ内に配置されることを意味します。たとえば、関数がこれらの値を閉じた場合、これは当てはまらない可能性があります。 JVMと同様に、プリミティブはローカル変数に格納されている場合にのみスタックに格納できます。

ユーザーとして、それはあなたが通常心配する必要があるものではありません。

15
Mathias Schwarz
  • V8では、nullundefinedtrue、およびfalseは内部的に ヒープ割り当てオブジェクト です。 Javaから来ている場合、V8のtruefalseはJavaのBoolean.TRUEBoolean.FALSEに似ていると言えます。 。
  • realローカル変数と、クロージャーによってキャプチャされるか、eval/withによってシャドウされる変数の間には重要な違いがあります。キャプチャ変数は、 Context と呼ばれる特別なヒープ割り当て構造に格納され、間接的にアクセスされます。 realとコンテキスト割り当て変数の詳細については、 別の質問に対する私の回答 を参照してください。
  • V8には、非最適化(別名フル)と最適化の2つのコンパイラがあります。

    • 非最適化コンパイラは、31ビット(x64では32ビット)を超える浮動小数点数と整数をスタックに格納できず、常にそれらを HeapNumber sにボックス化します。レジスタ割り当てを実行しようとせず、realローカル変数をスタックに格納します。
    • コンパイラの最適化ははるかに賢いです。レジスタ割り当て(線形スキャン)を実行し、スタックとレジスタ(XMMレジスタを含む)に完全な32ビット整数と浮動小数点数を保持できます。
  • JVMと言えば、いわゆるスタック割り当てを実行し、ヒープの代わりにスタックにエスケープしないオブジェクトを割り当てることができます。より一般的な最適化(スカラー置換)は、エスケープしないオブジェクトの割り当てを完全に排除し、それを別々のフィールドに分解できる場合があります。

33

最も一般的な用語では、Yes V8は機能にヒープとスタックを使用し、一般的なローカル変数はスタックに格納され、保守が必要なオブジェクトはヒープに格納されます。

0
kg11