Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8835

Google Chrome の JavaScript エンジン V8 って?

$
0
0

はじめに

V8 エンジンは、Google のオープンソースで Javascript, WebAssembly のエンジンです。
V8 は、 C++ で書かれており、Google Chrome や Node.js で動いています。

Javascript はどうやって動いているの?

V8 エンジンは、2つのコンポーネントで構成されています。

  1. Meomry Heap(メモリの割り当てなど)
  2. Call Stack(コードを実行するためのスタック)

Javascript から使える API (setTimeoutなど)には様々なものがありますが、これらは V8 エンジンから提供しているものではなく、ブラウザによって、提供されているものです。

Call Stack

Javascript は、シングルスレッドで動くので、Call Stack もシリアルに動きます。

例えば、このようなコードがあるとします。

functionmultiply(x,y){returnx*y;}functionprintSquare(x){vars=multiply(x,x);console.log(s);}printSquare(5);

すると、以下のようにスタックされます。

call stack.png

エラーが throw される場合もこの CallStack が使われているので、エラーを辿ることができます。

functionfoo(){thrownewError('SessionStack will help you resolve crashes :)');}functionbar(){foo();}functionstart(){bar();}start();

スクリーンショット 2020-08-16 1.10.59.png

また、無限ループの処理をする際は、このようになります。

functionfoo(){foo();}foo();

call stack 2.png

このエラーはシングルスレッドなので見つかりやすいですが、マルチスレッドになると少し複雑になります。しかし、その分シングルスレッドでの処理は遅くなってしまいます。

並行性とイベントループ

例えば、画像を変換する処理など時間がかかる処理をするプログラムがあった場合になかなか表示されないページを見たことがあるかもしれません。
その時はダイアログで警告されます。
スクリーンショット 2020-08-16 1.24.34.png

こういったサイトは、UX 的にとても残念なページですね。

これを解消するために asynchronous callbacksを使った方法があります。

TurboFan コンパイラ, Ignition インタプリタ

Javascript は、 JIT (just-in-time compile) で動作しているので、いくつかのトレードオフが存在します。

  1. コンパイルして生成されたネイティブコードは、実行されるピーク時の速度が早い一方で、コードの量が多いほど、最初に実行されるまでに遅延が発生する。一方で、トランスレーターを使った場合は、実行されるまでの遅延は小さいけど、実行時の速度が遅い。
  2. JavaScriptエンジンは、パフォーマンスを良くしようとするとメモリの消費量が多くなる。一方で、省メモリを進めようとするとパフォーマンスは悪化する。

これらを最適化するため、V8 では様々な改善が行われてきました。V8 のバージョン 5.9 までは2つのコンパイラが使われていましたが、現在では、TurboFan コンパイラ, Ignition インタプリタが使われています。
スクリーンショット 2020-08-16 1.44.32.png

Ignition インタプリタ

中間コードを生成して実行するインタプリタ。メモリ消費が小さく動く、Fast Startupも最適という特徴があります。

  • モバイルなどのメモリの小さな環境で動かすのに最適
  • Startup Timeに最適化すべきコードの実行に向いている
  • TurboFanと組み合わせることで、実行速度を最適化できる

TurboFan コンパイラ

主として、最適化を行うことを目的としたコンパイラです。

使われ方としては、拡張的な感じになります。ただ、あらゆる新しいJavaScript機能に対応していき、その場合も活用されます。
WebAssembly のバックエンドでもあります。
最近はtry/catch/finallyとか、ES2015+の最適化が可能になりました。

おわりに

V8 のコンパイラについては、いろいろと最適化が繰り返され、今のシンプルな形になっています。こうすることで管理しやすくしているのか思います。Web エンジニアとしては、V8 の仕組みはしっかり知っておきたいですが、まだまだわからないところも多いです。また、ガベージコレクションまでは書ききれませんでしたので、その辺はまた別の機会に書いてみたいと思います。

参考

https://v8.dev/docs


Viewing all articles
Browse latest Browse all 8835

Trending Articles