對(duì)于了解Node的開(kāi)發(fā)人員,我們都知道Node是基于Chrome V8引擎開(kāi)發(fā)的能使JavaScript在服務(wù)器端運(yùn)行的運(yùn)行時(shí)環(huán)境(runtime environment)。一方面,它提供了多種可調(diào)用的API,如讀寫(xiě)文件、網(wǎng)絡(luò)請(qǐng)求、系統(tǒng)信息等。另一方面,因?yàn)?b>CPU執(zhí)行的是機(jī)器碼,它還負(fù)責(zé)將JavaScript代碼解釋成機(jī)器指令序列執(zhí)行,這部分工作是由V8引擎完成。
MotivationJavaScript 是一款擁有「自動(dòng)垃圾回收」功能的編程語(yǔ)言。
市面上具有這樣功能的語(yǔ)言,一般都是擁有相對(duì)應(yīng)的虛擬機(jī)的,像 Java的JVM ,C#的CLR ,PHP的Zend。
虛擬機(jī)一般實(shí)現(xiàn)了代碼解析,內(nèi)存的管理、布局、垃圾回收等功能。
不像C/C++這種沒(méi)有虛擬機(jī)的語(yǔ)言,它們需要手動(dòng)管理內(nèi)存。
C/C++語(yǔ)言編譯后的文件,是可以直接運(yùn)行的。
我認(rèn)為學(xué)習(xí)一門(mén)開(kāi)發(fā)語(yǔ)言,除了知道一些語(yǔ)法上的使用,各種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ā)量上來(lái)了,一些很細(xì)小的問(wèn)題會(huì)放大。這時(shí)候一些小小的內(nèi)存泄漏,都會(huì)釀造災(zāi)難。
所以作為一個(gè) JavaScript 開(kāi)發(fā)者,搞清楚從敲入 console.log("hello world") ,直到后面交由CPU執(zhí)行的中間過(guò)程是很重要的。
這也對(duì)如何用 JavaScript 這門(mén)松散的語(yǔ)言編寫(xiě)出高質(zhì)量的代碼是具有指導(dǎo)作用的。
想真正做到 JavaScript 全棧,路漫漫其修遠(yuǎn)兮。
NodeJS 概述根據(jù)百度百科解釋,Node.js是一套用來(lái)編寫(xiě)高性能網(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,也就是說(shuō),實(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源碼—>抽象語(yǔ)法樹(shù)—>本地機(jī)器碼,并且后一個(gè)步驟只依賴前一個(gè)步驟。這與其他解釋器不同,例如Java語(yǔ)言需要先將源碼編譯成字節(jié)碼,然后給JVM解釋執(zhí)行,JVM根據(jù)優(yōu)化策略,運(yùn)行過(guò)程中有選擇地將一部分字節(jié)碼編譯成本地機(jī)器碼。V8不生成中間代碼,一步到位,編譯成機(jī)器碼,CPU就開(kāi)始執(zhí)行了。比起生成中間碼解釋執(zhí)行的方式,V8的策略省去了一個(gè)步驟,程序會(huì)更早地開(kāi)始運(yùn)行。并且執(zhí)行編譯好的機(jī)器指令,也比解釋執(zhí)行中間碼的速度更快。不足的是,缺少字節(jié)碼這個(gè)中間表示,使得代碼優(yōu)化變得更困難。
V8 概述V8 作為一個(gè) JavaScript 引擎,最初是服役于 Google Chrome 瀏覽器的。它隨著 Chrome 的第一版發(fā)布而發(fā)布以及開(kāi)源。現(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,并沒(méi)有二進(jìn)制碼或其他的中間碼。
簡(jiǎn)單來(lái)說(shuō),V8主要工作就是:「把 JavaScript 直譯成機(jī)器碼,然后運(yùn)行」
但這中間,往往是一個(gè)復(fù)雜的過(guò)程,它需要處理很多的難題,諸如:
編譯優(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++編寫(xiě)的核心模塊所在文件夾,由C/C++編寫(xiě)的這部分模塊被稱為「Builtin Module」
/lib :由JavaScript編寫(xiě)的核心模塊所在文件夾,這部分被稱為「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 文件。
來(lái)張圖說(shuō)明一下V8在Node運(yùn)行時(shí)的整體過(guò)程。
Node在啟動(dòng)的時(shí)候,就已經(jīng)把 Native Module,Builtin Module 加載到內(nèi)存里面了。后來(lái)的 JavaScript 代碼,就需要通過(guò) 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://m.specialneedsforspecialkids.com/yun/107769.html
摘要:垃圾回收內(nèi)存管理實(shí)踐先通過(guò)一個(gè)來(lái)看看在中進(jìn)行垃圾回收的過(guò)程是怎樣的內(nèi)存泄漏識(shí)別在環(huán)境里提供了方法用來(lái)查看當(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)行過(guò)程中的大部分?jǐn)?shù)據(jù)都保存在堆中,所以性能分析另一個(gè)比較重要的方面是內(nèi)存,也就是堆的分析。上周發(fā)布了工具,可以用來(lái)動(dòng)態(tài)地展示的結(jié)果,分析各種函數(shù)的調(diào)用關(guān)系。 OneHeap 關(guān)注于運(yùn)行中的 JavaScript 內(nèi)存信息的展示,用可視化的方式還原了 HeapGraph,有助于理解 v8 內(nèi)存管理。 ...
摘要:文本已收錄至我的倉(cāng)庫(kù),歡迎前后端分離這個(gè)詞相信大家都聽(tīng)過(guò),不知道大家是怎么理解的呢。流下不學(xué)無(wú)術(shù)的淚水目前我了解到的前后端分離,首先部署是分離的至少不會(huì)跟綁定在一起部署接口只返回?cái)?shù)據(jù)關(guān)于前端這幾大框架這幾個(gè)我都是沒(méi)有寫(xiě)過(guò)的,所以也就不多了。 前言 只有光頭才能變強(qiáng)。文本已收錄至我的GitHub倉(cāng)庫(kù),歡迎Star:https://github.com/ZhongFuCheng3y/3y ...
摘要:查詢是在作用域鏈中,一級(jí)級(jí)的往上查找該變量的引用。作用域和作用域鏈作用域的概念,應(yīng)該兩張圖幾句話就能解釋吧。這個(gè)建筑代表程序中的嵌套作用域鏈。一層嵌一層的作用域形成了作用域鏈,變量在作用域鏈中的函數(shù)內(nèi)得到了自己的定義。 javascript作用域和閉包之我見(jiàn) 看了《你不知道的JavaScript(上卷)》的第一部分——作用域和閉包,感受頗深,遂寫(xiě)一篇讀書(shū)筆記加深印象。路過(guò)的大牛歡迎指點(diǎn)...
摘要:什么是在中什么時(shí)候需要是中的包管理器。允許我們?yōu)榘惭b各種模塊,這個(gè)包管理器為我們提供了安裝刪除等其它命令來(lái)管理模塊。 showImg(https://user-gold-cdn.xitu.io/2019/7/11/16bde5b2df52a924?w=4000&h=2667&f=jpeg&s=450648); 本文為您分享「Node.js 入門(mén)你需要知道的 10 個(gè)問(wèn)題」這些問(wèn)題可能也...
閱讀 2604·2021-11-17 09:33
閱讀 3958·2021-10-19 11:46
閱讀 916·2021-10-14 09:42
閱讀 2261·2021-09-22 15:41
閱讀 4233·2021-09-22 15:20
閱讀 4638·2021-09-07 10:22
閱讀 2314·2021-09-04 16:40
閱讀 821·2019-08-30 15:52