對(duì)于了解Node的開發(fā)人員,我們都知道Node是基于Chrome V8引擎開發(fā)的能使JavaScript在服務(wù)器端運(yùn)行的運(yùn)行時(shí)環(huán)境(runtime environment)。一方面,它提供了多種可調(diào)用的API,如讀寫文件、網(wǎng)絡(luò)請(qǐng)求、系統(tǒng)信息等。另一方面,因?yàn)?b>CPU執(zhí)行的是機(jī)器碼,它還負(fù)責(zé)將JavaScript代碼解釋成機(jī)器指令序列執(zhí)行,這部分工作是由V8引擎完成。
MotivationJavaScript 是一款擁有「自動(dòng)垃圾回收」功能的編程語言。
市面上具有這樣功能的語言,一般都是擁有相對(duì)應(yīng)的虛擬機(jī)的,像 Java的JVM ,C#的CLR ,PHP的Zend。
虛擬機(jī)一般實(shí)現(xiàn)了代碼解析,內(nèi)存的管理、布局、垃圾回收等功能。
不像C/C++這種沒有虛擬機(jī)的語言,它們需要手動(dòng)管理內(nèi)存。
C/C++語言編譯后的文件,是可以直接運(yùn)行的。
我認(rèn)為學(xué)習(xí)一門開發(fā)語言,除了知道一些語法上的使用,各種API的調(diào)用以外。學(xué)習(xí)相應(yīng)的虛擬機(jī)也是很有必要的。而 JavaScript 由于其特殊的歷史原因,并不是只有 V8 一個(gè)引擎。但是目前 V8 它是業(yè)界最優(yōu)秀的 JavaScript 引擎,也就成為了一個(gè)學(xué)習(xí)樣本。
如今的 JavaScript 不僅僅是用在瀏覽器端了,也因?yàn)?NodeJS 的關(guān)系得以在服務(wù)器端運(yùn)行。和瀏覽器端不同的地方在于服務(wù)器端對(duì)資源的敏感性是很高的。當(dāng)業(yè)務(wù)規(guī)模大了,并發(fā)量上來了,一些很細(xì)小的問題會(huì)放大。這時(shí)候一些小小的內(nèi)存泄漏,都會(huì)釀造災(zāi)難。
所以作為一個(gè) JavaScript 開發(fā)者,搞清楚從敲入 console.log("hello world") ,直到后面交由CPU執(zhí)行的中間過程是很重要的。
這也對(duì)如何用 JavaScript 這門松散的語言編寫出高質(zhì)量的代碼是具有指導(dǎo)作用的。
想真正做到 JavaScript 全棧,路漫漫其修遠(yuǎn)兮。
NodeJS 概述根據(jù)百度百科解釋,Node.js是一套用來編寫高性能網(wǎng)絡(luò)服務(wù)器的JavaScript工具包。Node.js是一個(gè)可以快速構(gòu)建網(wǎng)絡(luò)服務(wù)及應(yīng)用的平臺(tái),該平臺(tái)的構(gòu)建是基于Chrome"s JavaScript runtime,也就是說,實(shí)際上它是對(duì)GoogleV8引擎(應(yīng)用于Google Chrome瀏覽器)進(jìn)行了封裝。V8引 擎執(zhí)行Javascript的速度非???,性能非常好。
NodeJS并不是提供簡(jiǎn)單的封裝,然后提供API調(diào)用,如果是這樣的話那么它就不會(huì)有現(xiàn)在這么火了。Node對(duì)一些特殊用例進(jìn)行了優(yōu)化,提供了替代的API,使得V8在非瀏覽器環(huán)境下運(yùn)行得更好。例如,在服務(wù)器環(huán)境中,處理二進(jìn)制數(shù)據(jù)通常是必不可少的,但Javascript對(duì)此支持不足,因此,V8.Node增加了Buffer類,方便并且高效地 處理二進(jìn)制數(shù)據(jù)。因此,Node不僅僅簡(jiǎn)單的使用了V8,還對(duì)其進(jìn)行了優(yōu)化,使其在各環(huán)境下更加給力。
即時(shí)編譯JIT 概述V8采用即時(shí)編譯技術(shù)(JIT),直接將JavaScript代碼編譯成本地平臺(tái)的機(jī)器碼。宏觀上看,其步驟為JavaScript源碼—>抽象語法樹—>本地機(jī)器碼,并且后一個(gè)步驟只依賴前一個(gè)步驟。這與其他解釋器不同,例如Java語言需要先將源碼編譯成字節(jié)碼,然后給JVM解釋執(zhí)行,JVM根據(jù)優(yōu)化策略,運(yùn)行過程中有選擇地將一部分字節(jié)碼編譯成本地機(jī)器碼。V8不生成中間代碼,一步到位,編譯成機(jī)器碼,CPU就開始執(zhí)行了。比起生成中間碼解釋執(zhí)行的方式,V8的策略省去了一個(gè)步驟,程序會(huì)更早地開始運(yùn)行。并且執(zhí)行編譯好的機(jī)器指令,也比解釋執(zhí)行中間碼的速度更快。不足的是,缺少字節(jié)碼這個(gè)中間表示,使得代碼優(yōu)化變得更困難。
V8 概述V8 作為一個(gè) JavaScript 引擎,最初是服役于 Google Chrome 瀏覽器的。它隨著 Chrome 的第一版發(fā)布而發(fā)布以及開源?,F(xiàn)在它除了 Chrome 瀏覽器,已經(jīng)有很多其他的使用者了。諸如 NodeJS、MongoDB、CouchDB 等。
JavaScript 作為 Prototype-Based Language , 基于它使用 Prototype 繼承的特征,V8 使用了直譯的方式,即把 JavaScript 代碼直接編譯成機(jī)器碼( Machine Code, 有些地方也叫 Native Code ),然后直接交由硬件執(zhí)行。
與傳統(tǒng)的「編譯-解析-執(zhí)行」的流程不同,V8 處理 JavaScript,并沒有二進(jìn)制碼或其他的中間碼。
簡(jiǎn)單來說,V8主要工作就是:「把 JavaScript 直譯成機(jī)器碼,然后運(yùn)行」
但這中間,往往是一個(gè)復(fù)雜的過程,它需要處理很多的難題,諸如:
編譯優(yōu)化 內(nèi)存管理 垃圾回收V8 In NodeJS/NodeJS源碼小覽
NodeJS,是怎么引入V8的?
我們關(guān)注 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 │ ├── ... ├── ...
需要關(guān)注的幾個(gè)目錄和文件:
/deps/v8 :這里是V8源碼所在文件夾,你會(huì)發(fā)現(xiàn)里面的目錄結(jié)構(gòu)跟 V8源碼 十分相似。NodeJS除了移植V8源碼,還在增添了一些內(nèi)容。
/src :由C/C++編寫的核心模塊所在文件夾,由C/C++編寫的這部分模塊被稱為「Builtin Module」
/lib :由JavaScript編寫的核心模塊所在文件夾,這部分被稱為「Native Code」,在編譯Node源碼的時(shí)候,會(huì)采用V8附帶的 js2c.py 工具,把所有內(nèi)置的JavaScript代碼轉(zhuǎn)換成C++里面的數(shù)組,生成 out/Release/obj/gen/node_natives.h 文件。有些 Native Module 需要借助于 Builtin Module 實(shí)現(xiàn)背后的功能。
/out :該目錄是Node源碼編譯(命令行運(yùn)行 make )后生成的目錄,里面包含了Node的可執(zhí)行文件。當(dāng)在命令行中鍵入 node xxx.js ,實(shí)際就是運(yùn)行了 out/Release/node 文件。
來張圖說明一下V8在Node運(yùn)行時(shí)的整體過程。
Node在啟動(dòng)的時(shí)候,就已經(jīng)把 Native Module,Builtin Module 加載到內(nèi)存里面了。后來的 JavaScript 代碼,就需要通過 V8 進(jìn)行動(dòng)態(tài)編譯解析運(yùn)行。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107769.html
摘要:垃圾回收內(nèi)存管理實(shí)踐先通過一個(gè)來看看在中進(jìn)行垃圾回收的過程是怎樣的內(nèi)存泄漏識(shí)別在環(huán)境里提供了方法用來查看當(dāng)前進(jìn)程內(nèi)存使用情況,單位為字節(jié)中保存的進(jìn)程占用的內(nèi)存部分,包括代碼本身?xiàng)6选? showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技術(shù)棧 | https:...
摘要:關(guān)注于運(yùn)行中的內(nèi)存信息的展示,用可視化的方式還原了,有助于理解內(nèi)存管理。背景運(yùn)行過程中的大部分?jǐn)?shù)據(jù)都保存在堆中,所以性能分析另一個(gè)比較重要的方面是內(nèi)存,也就是堆的分析。上周發(fā)布了工具,可以用來動(dòng)態(tài)地展示的結(jié)果,分析各種函數(shù)的調(diào)用關(guān)系。 OneHeap 關(guān)注于運(yùn)行中的 JavaScript 內(nèi)存信息的展示,用可視化的方式還原了 HeapGraph,有助于理解 v8 內(nèi)存管理。 ...
摘要:文本已收錄至我的倉庫,歡迎前后端分離這個(gè)詞相信大家都聽過,不知道大家是怎么理解的呢。流下不學(xué)無術(shù)的淚水目前我了解到的前后端分離,首先部署是分離的至少不會(huì)跟綁定在一起部署接口只返回?cái)?shù)據(jù)關(guān)于前端這幾大框架這幾個(gè)我都是沒有寫過的,所以也就不多了。 前言 只有光頭才能變強(qiáng)。文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y ...
摘要:查詢是在作用域鏈中,一級(jí)級(jí)的往上查找該變量的引用。作用域和作用域鏈作用域的概念,應(yīng)該兩張圖幾句話就能解釋吧。這個(gè)建筑代表程序中的嵌套作用域鏈。一層嵌一層的作用域形成了作用域鏈,變量在作用域鏈中的函數(shù)內(nèi)得到了自己的定義。 javascript作用域和閉包之我見 看了《你不知道的JavaScript(上卷)》的第一部分——作用域和閉包,感受頗深,遂寫一篇讀書筆記加深印象。路過的大牛歡迎指點(diǎn)...
摘要:什么是在中什么時(shí)候需要是中的包管理器。允許我們?yōu)榘惭b各種模塊,這個(gè)包管理器為我們提供了安裝刪除等其它命令來管理模塊。 showImg(https://user-gold-cdn.xitu.io/2019/7/11/16bde5b2df52a924?w=4000&h=2667&f=jpeg&s=450648); 本文為您分享「Node.js 入門你需要知道的 10 個(gè)問題」這些問題可能也...
閱讀 2656·2021-11-17 09:33
閱讀 4054·2021-10-19 11:46
閱讀 974·2021-10-14 09:42
閱讀 2313·2021-09-22 15:41
閱讀 4326·2021-09-22 15:20
閱讀 4729·2021-09-07 10:22
閱讀 2378·2021-09-04 16:40
閱讀 864·2019-08-30 15:52