nodejs與v8

Motivation

JavaScript 是一款擁有「自動垃圾回收」功能的編程語言。node

市面上具備這樣功能的語言,通常都是擁有相對應的虛擬機的,像 Java的JVM ,C#的CLR ,PHP的Zend。git

虛擬機通常實現了代碼解析,內存的管理、佈局、垃圾回收等功能。github

不像C/C++這種沒有虛擬機的語言,它們須要手動管理內存。編程

C/C++語言編譯後的文件,是能夠直接運行的。數組

我認爲學習一門開發語言,除了知道一些語法上的使用,各類API的調用之外。學習相應的虛擬機也是頗有必要的。而 JavaScript 因爲其特殊的歷史緣由,並非只有 V8 一個引擎。可是目前 V8 它是業界最優秀的 JavaScript 引擎,也就成爲了一個學習樣本。瀏覽器

現在的 JavaScript 不單單是用在瀏覽器端了,也由於 NodeJS 的關係得以在服務器端運行。和瀏覽器端不一樣的地方在於服務器端對資源的敏感性是很高的。當業務規模大了,併發量上來了,一些很細小的問題會放大。這時候一些小小的內存泄漏,都會釀造災難。服務器

因此做爲一個 JavaScript 開發者,搞清楚從敲入 console.log('hello world') ,直到後面交由CPU執行的中間過程是很重要的。併發

這也對如何用 JavaScript 這門鬆散的語言編寫出高質量的代碼是具備指導做用的。編程語言

想真正作到 JavaScript 全棧,路漫漫其修遠兮。工具

V8 概述

V8 做爲一個 JavaScript 引擎,最初是服役於 Google Chrome 瀏覽器的。它隨着 Chrome 的初版發佈而發佈以及開源。如今它除了 Chrome 瀏覽器,已經有不少其餘的使用者了。諸如 NodeJS、MongoDB、CouchDB 等。

JavaScript 做爲 Prototype-Based Language , 基於它使用 Prototype 繼承的特徵,V8 使用了直譯的方式,即把 JavaScript 代碼直接編譯成機器碼( Machine Code, 有些地方也叫 Native Code ),而後直接交由硬件執行。

與傳統的「編譯-解析-執行」的流程不一樣,V8 處理 JavaScript,並無二進制碼或其餘的中間碼。

簡單來講,V8主要工做就是:「把 JavaScript 直譯成機器碼,而後運行」

但這中間,每每是一個複雜的過程,它須要處理不少的難題,諸如:

  1. 編譯優化

  2. 內存管理

  3. 垃圾回收

我寫的這一系列文章,也是從這三個大點來出發,解讀V8針對這些內容的處理。

V8 In NodeJS

NodeJS源碼小覽

NodeJS,是怎麼引入V8的?

咱們關注 Node的源碼 目錄:

.
├── ...
├── deps
│   ├── ...
│   ├── v8
│   ├── ...
├── ...
├── lib
│   ├── ...
│   ├── buffer.js
│   ├── child_process.js
│   ├── console.js
│   ├── ...
├── node -> out/Release/node
├── ...
├── out
│   ├── ...
│   ├── Release
|         ├── node
|         ├── node.d
|         ├── obj
|             └── gen
|                 ├── ...
|                 ├── node_natives.h
|                 ├── ...
│   ├── ...
├── src
│   ├── ...
│   ├── debug-agent.cc
│   ├── debug-agent.h
│   ├── env-inl.h
│   ├── env.cc
│   ├── ...
├── 
...

須要關注的幾個目錄和文件:

/deps/v8 :這裏是V8源碼所在文件夾,你會發現裏面的目錄結構跟 V8源碼 十分類似。NodeJS除了移植V8源碼,還在增添了一些內容。

/src :由C/C++編寫的核心模塊所在文件夾,由C/C++編寫的這部分模塊被稱爲「Builtin Module」

/lib :由JavaScript編寫的核心模塊所在文件夾,這部分被稱爲「Native Code」,在編譯Node源碼的時候,會採用V8附帶的 js2c.py 工具,把全部內置的JavaScript代碼轉換成C++裏面的數組,生成 out/Release/obj/gen/node_natives.h 文件。有些 Native Module 須要藉助於 Builtin Module 實現背後的功能。

/out :該目錄是Node源碼編譯(命令行運行 make )後生成的目錄,裏面包含了Node的可執行文件。當在命令行中鍵入 node xxx.js ,實際就是運行了 out/Release/node 文件。

來張圖說明一下V8在Node運行時的總體過程。

Node在啓動的時候,就已經把 Native Module,Builtin Module 加載到內存裏面了。後來的 JavaScript 代碼,就須要經過 V8 進行動態編譯解析運行。

相關文章
相關標籤/搜索