<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # 常見的 JS解析器 JavaScript 虛擬機是一種進程虛擬機,專門設計來解釋和執行的 JavaScript代碼。 ![](https://img.kancloud.cn/03/9d/039d58b0098fa2dd6a3b9cc4fe88dc85_1015x534.png) # JavaScript vs C++ c++是編譯型語言,在程序執行之前必須進行專門的編譯過程,在生成本地代碼的過程中,變量的地址和類型已經確定,運行本地代碼時利用數組和位移就可以存取變量和方法的地址,不需要再進行額外的查找,幾個機器指令即可完成,節省了確定類型和地址的時間,執行效率高 JavaScript是解釋行語言,支持動態類型,弱類型,在程序運行的時候才進行編譯,而編譯前需要確定變量的類型,效率比較低,對不同系統平臺有較大的兼容性(跨平臺性好),需要快速地執行和解析JavaScript腳本來提高性能,V8因此而誕生 # V8引擎誕生 **v8是谷歌開源的一個基于C++語言開發的JavaScript引擎**,可以實現ECMA-262中規定的ECMAScript,其被用于谷歌瀏覽器chrome,安卓瀏覽器,node.js等大型項目當中,V8引擎可以獨立運行不依賴于其他環境,也可以嵌入任何的C++應用當中使用。 # V8工作流程 V8將JavaScript代碼進行編譯,生成抽象語法樹(AST),對作用域進行分析,分辨出局部變量或全局變量,再通過JIT技術將語法樹直接轉換成原生代碼,沒有經過字節碼的編譯,節省了編譯時間,得到了不是最優的代碼,其后通過數據分析器挑選使用頻率高的代碼進行優化,若優化后的效果不如之前的話就進行優化回滾。 ![抽象語法樹](https://img.kancloud.cn/12/e3/12e3edd75c2d6fbef5f902ae1a203d66_693x216.png) # V8 vs JavaScriptCore JavaScriptCore是WebKit中默認的JavaScript引擎,它是蘋果開源的一個項目,是蘋果Safari瀏覽器的JavaScript引擎,應用較為廣泛。 * JavaScriptCore的大致流程:JavaScript源代碼 -> 抽象語法樹(AST)-> 字節碼-> 本地代碼 * V8的大致流程:JavaScript源代碼 -> 抽象語法樹(AST)-> 本地代碼 (2017年4月發布5.9版本后新增了Ignition字節碼解釋器,與JScore流程大致相同) V8引擎并不將抽象語法樹轉變成字節碼或者其它中間表示,沒有像 Java 一樣的虛擬機或者字節碼解釋器。 > 這樣做的原因? > **主要是為了減少這抽象語法樹到字節碼的轉換時間,這一切都在網頁加載時候完成,雖然可以提高優化的可能,但是這些分析可能帶來巨大的時間浪費。** # V8特性 ## 兩種編譯器:full compiler 和 crankshaft(后來在5.9版本后被消除) * full compiler: full compiler是不含優化的編譯器,目標是快速地生成原生代碼,以保持頁面始終快速運轉,所以full compiler省去了將語法樹(AST)轉換為字節碼的過程,直接生成原生代碼。 * crankshaft: 由于full compiler沒有對代碼進行優化,所以V8引入了crankshaft編譯器,通過數據分析器來挑選使用頻率高的函數來進行優化,生成高效的原生代碼,但是鑒于JavaScript是一門動態類型語言,很有可能在程序運行過程中進行類型改變,所以V8會將crankshaft編譯過的代碼進行優化回滾,直至回滾到當前最優狀態。 ## 內聯緩存(Inline caches, ICs) 由于JavaScript是一門動態類型語言,在很多操作上會相當復雜,可能一個簡單的操作符都會引發起上百條指令。而V8中使用了內聯緩存的機制,大致就是一個包含了對某個操作的多種實現方案的函數,在程序運行的時候動態生成并且緩存起來,方便重用,當再次訪問的時候進行判斷是否可以直接使用緩存結果,這樣減少了很大的工作量。 ## 隱藏類 JavaScript訪問對象屬性的時候是通過匹配字符串的形式來查找的,而V8借鑒了C++語言中類和偏移位置的思想,實現了隱藏類,將對象按照屬性是否相同劃分到不同的組當中,將這些組的屬性名和對應的偏移位置保存在一個隱藏類中,組內所有對象共享該信息。假如對象中新增了新的屬性,那么這個對象就會被劃分到一個新的隱藏類當中。 ## 垃圾回收 JavaScript使用了垃圾回收的機制,也意味著程序中是不能對內存進行管理的,這樣的好處是無需程序員來額外操作內存問題,防止內存泄漏,但是壞處是無法對內存進行控制也無法對垃圾回收器進行反饋。 垃圾回收器意味著識別到需要回收的內存,將其重新分配或返還給操作系統。先看看V8的內存管理,V8將數據分為新生代,老生代和大對象區。 * 新生代:為新創建的對象分配內存空間,經常需要進行垃圾回收。為方便年輕分代中的內容回收,可再將年輕分代分為兩半,一半用來分配,另一半在回收時負責將之前還需要保留的對象復制過來。我們只需保有一個指向內存區的指針,不斷根據新對象的大小對其進行遞增即可。當該指針達到了新生代區的末尾,就會有一次清理,清理掉新生代區中不活躍的死對象。 * 老生代:字符串、封箱的數字以及未封箱的雙精度數字數組,在新生區存活一段時間后會被移動到這里。根據需要將年老的對象、指針、代碼等數據保存起來,較少地進行垃圾回收。 * 大對象區:為那些需要使用較多內存對象分配內存,當然同樣可能包含數據和代碼等分配的內存,一個頁面只分配一個對象。垃圾回收器從不移動大對象。 在新生代中垃圾回收主要采用Scavenge算法,新生代區被劃分為兩個等大的子區:出區、入區。絕大多數內存的分配都會在出區發生,當出區耗盡時,我們交換出區和入區(這樣所有的對象都歸屬在入區當中),然后將入區中活躍的對象復制至出區或老生代區當中。 在老生區中,V8在標記-清除或標記-緊縮(大周期)的過程中進行回收。大周期進行的并不頻繁。一次大周期通常是在移動足夠多的對象至老生區后才會發生。至于足夠多到底是多少,則根據老生區自身的大小和程序的動向來定。 # V8后續發展 在2017年4月V8發布的5.9 版本中,V8團隊收集了JavaScript的實測性能并仔細分析了Full-codegen的缺點和Crankshaft,新增了一個 Ignition字節碼解釋器,TurboFan和Ignition結合起來共同完成JavaScript的編譯。關于更多TurboFan and Ignition的資料,可以參考:[https://cnodejs.org/topic/59084a9cbbaf2f3f569be482](https://cnodejs.org/topic/59084a9cbbaf2f3f569be482)和[http://benediktmeurer.de/2016/11/25/v8-behind-the-scenes-november-edition/](http://benediktmeurer.de/2016/11/25/v8-behind-the-scenes-november-edition/) # 參考 [JavaScript引擎](https://blog.csdn.net/liwenfei123/article/details/80677670) [淺讀V8——強大的JavaScript引擎](https://www.jianshu.com/p/332c15fd7c7d)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看