欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          javascript有g(shù)c嗎

          javascript中有GC(垃圾回收機制)。JavaScript是使用垃圾回收機制的語言,執(zhí)行環(huán)境負(fù)責(zé)在代碼執(zhí)行時管理內(nèi)存,會自動將垃圾對象(沒有被引用的對象)從內(nèi)存中銷毀。

          javascript有g(shù)c嗎

          本教程操作環(huán)境:windows7系統(tǒng)、javascript1.8.5版、Dell G3電腦。

          JavaScript 中的垃圾回收機制(GC)

          垃圾回收相關(guān)概念

          ① 什么是垃圾

          沒有被使用(引用)的對象就是垃圾。

          ② 什么是垃圾回收

          沒有被引用的對象被銷毀,內(nèi)存被釋放,就是垃圾回收

          C、C++ 等編程語言需要手動垃圾回收。

          Java、JavaScript、PHP、Python 等語言自動垃圾回收。

          JS中擁有自動的垃圾回收機制,會自動將這些垃圾對象從內(nèi)存中銷毀,我們不需要也不能進(jìn)行垃圾回收的操作。我們需要做的只是要將不再使用的對象設(shè)置為 null 即可。

          為什么需要垃圾回收

          • 在C / C++中,跟蹤內(nèi)存的使用和管理內(nèi)存對開發(fā)者來說是很大的負(fù)擔(dān)
            • JavaScript是使用垃圾回收機制的語言,也就是說執(zhí)行環(huán)境負(fù)責(zé)在代碼執(zhí)行時管理內(nèi)存,幫開發(fā)者卸下了這個負(fù)擔(dān)
            • 通過自動內(nèi)存管理實現(xiàn)內(nèi)存的分配和資源的回收
            • 基本思路很簡單,確定哪個變量不會再被使用了,把它的內(nèi)存空間釋放
            • 這個過程是周期性的,意思是這個垃圾回收程序每隔一段時間就會運行一次
          • 像JS中的對象、字符串、對象的內(nèi)存是不固定的,只有真正用到的時候才會動態(tài)分配內(nèi)存
            • 這些內(nèi)存需在不使用后進(jìn)行釋放以便再次使用,否則在計算機可用內(nèi)存耗盡后造成崩潰
          • 瀏覽器發(fā)展史上的垃圾回收法主要有
            • 引用計數(shù)法
            • 標(biāo)記清除法

          引用計數(shù)法

          思路

          • 變量只是對值進(jìn)行引用
          • 當(dāng)變量引用該值時,引用次數(shù)+1
          • 當(dāng)該變量的引用被覆蓋或者清除時,引用次數(shù)-1
          • 當(dāng)引用次數(shù)為0時,就可以安全地釋放這塊內(nèi)存。
          let arr = [1, 0, 1]   // [1, 0, 1]這塊內(nèi)存被arr引用  引用次數(shù)為1 arr = [0, 1, 0]  // [1, 0, 1]的內(nèi)存引用次數(shù)為0被釋放                    // [0, 1, 0]的內(nèi)存被arr引用   引用次數(shù)為1 const tmp = arr  // [0, 1, 0]的內(nèi)存被tmp引用   引用次數(shù)為2

          循環(huán)引用問題

          Netscape Navigator 3.0 采用

          • 在這個例子中,ObjectA和ObjectB的屬性分別相互引用
          • 造成這個函數(shù)執(zhí)行后,Object被引用的次數(shù)不會變成0,影響了正常的GC。
          • 如果執(zhí)行多次,將造成嚴(yán)重的內(nèi)存泄漏。
          • 而標(biāo)記清除法則不會出現(xiàn)這個問題。
          function Example(){      let ObjectA = new Object();     let ObjectB = new Object();      ObjectA.p = ObjectB;     ObjectB.p = ObjectA;     }  Example();
          • 解決方法:在函數(shù)結(jié)束時將其指向null
          ObjectA = null; ObjectB = null;

          標(biāo)記清除法

          為了解決循環(huán)引用造成的內(nèi)存泄漏問題,Netscape Navigator 4.0 開始采用標(biāo)記清除法

          到了 2008 年,IE、Firefox、Opera、Chrome 和 Safari 都在自己的 JavaScript 實現(xiàn)中采用標(biāo)記清理(或 其變體),只是在運行垃圾回收的頻率上有所差異。

          思路

          • 在變量進(jìn)入執(zhí)行上下文時打上“進(jìn)入”標(biāo)記
          • 同時在變量離開執(zhí)行上下文時也打上“離開”標(biāo)記
            • 從此以后,無法訪問這個變量
            • 在下一次垃圾回收時進(jìn)行內(nèi)存的釋放
          function Example(n){     const a = 1, b = 2, c = 3;     return n * a * b * c; } // 標(biāo)記Example進(jìn)入執(zhí)行上下文  const n = 1;  // 標(biāo)記n進(jìn)入執(zhí)行上下文 Example(n);   // 標(biāo)記a,b,c進(jìn)入執(zhí)行上下文 console.log(n); // 標(biāo)記a, b, c離開執(zhí)行上下文,等待垃圾回收

          const和let聲明提升性能

          • const和let不僅有助于改善代碼風(fēng)格,同時有利于垃圾回收性能的提升
          • const和let使JS有了塊級作用域,當(dāng)塊級作用域比函數(shù)作用域更早結(jié)束時,垃圾回收程序更早介入
          • 盡早回收該回收的內(nèi)存,提升了垃圾回收的性能

          V8引擎的垃圾回收

          V8引擎的垃圾回收采用標(biāo)記清除法與分代回收法

          分為新生代和老生代

          新生代

          新生代垃圾回收采用Scavenge 算法

          分配給常用內(nèi)存和新分配的小量內(nèi)存

          • 內(nèi)存大小

            • 32位系統(tǒng)16M內(nèi)存
            • 64位系統(tǒng)32M內(nèi)存
          • 分區(qū)

            • 新生代內(nèi)存分為以下兩區(qū),內(nèi)存各占一半
            • From space
            • To space
          • 運行

            • 實際運行的只有From space
            • To space處于空閑狀態(tài)
          • Scavenge算法

            • 當(dāng)From space內(nèi)存使用將要達(dá)到上限時開始垃圾回收,將From space中的不可達(dá)對象都打上標(biāo)記
            • 將From space的未標(biāo)記對象復(fù)制到To space。
              • 解決了內(nèi)存散落分塊的問題(不連續(xù)的內(nèi)存空間)
              • 相當(dāng)于用空間換時間。
            • 然后清空From space、將其閑置,也就是轉(zhuǎn)變?yōu)門o space,俗稱反轉(zhuǎn)。
          • 新生代 -> 老生代

            • 新生代存放的是新分配的小量內(nèi)存,如果達(dá)到以下條件中的一個,將被分配至老生代
              • 內(nèi)存大小達(dá)到From space的25%
              • 經(jīng)歷了From space <-> To space的一個輪回

          javascript有g(shù)c嗎

          老生代

          老生代采用mark-sweep標(biāo)記清除和mark-compact標(biāo)記整理

          通常存放較大的內(nèi)存塊和從新生代分配過來的內(nèi)存塊

          • 內(nèi)存大小
            • 32位系統(tǒng)700M左右
            • 64位系統(tǒng)1.4G左右
          • 分區(qū)
            • Old Object Space
              • 字面的老生代,存放的是新生代分配過來的內(nèi)存。
            • Large Object Space
              • 存放其他區(qū)域放不下的較大的內(nèi)存,基本都超過1M
            • Map Space
              • 存放存儲對象的映射關(guān)系
            • Code Space
              • 存儲編譯后的代碼
          • 回收流程
            • 標(biāo)記分類(三色標(biāo)記)
              • 未被掃描,可回收,下面簡稱1類
              • 掃描中,不可回收,下面簡稱2類
              • 掃描完成,不可回收,下面簡稱3類
            • 遍歷
              • 采用深度優(yōu)先遍歷,遍歷每個對象。
              • 首先將非根部對象全部標(biāo)記為1類,然后進(jìn)行深度優(yōu)先遍歷。
              • 遍歷過程中將對象壓入棧,這個過程中對象被標(biāo)記為2類
              • 遍歷完成對象出棧,這個對象被標(biāo)記為3類
              • 整個過程直至???/li>
            • Mark-sweep
              • 標(biāo)記完成之后,將標(biāo)記為1類的對象進(jìn)行內(nèi)存釋放

          • javascript有g(shù)c嗎

          • Mark-compact

            • 垃圾回收完成之后,內(nèi)存空間是不連續(xù)的。

            • 這樣容易造成無法分配較大的內(nèi)存空間的問題,從而觸發(fā)垃圾回收。

            • 所以,會有Mark-compact步驟將未被回收的內(nèi)存塊整理為連續(xù)地內(nèi)存空間。

            • 頻繁觸發(fā)垃圾回收會影響引擎的性能,內(nèi)存空間不足時也會優(yōu)先觸發(fā)Mark-compact

          javascript有g(shù)c嗎

          垃圾回收優(yōu)化

          • 增量標(biāo)記
            • 如果用集中的一段時間進(jìn)行垃圾回收,新生代倒還好,老生代如果遍歷較大的對象,可能會造成卡頓。
            • 增量標(biāo)記:使垃圾回收程序和應(yīng)用邏輯程序交替運行,思想類似Time Slicing
          • 并行回收
            • 在垃圾回收的過程中,開啟若干輔助線程,提高垃圾回收效率。
          • 并發(fā)回收
            • 在邏輯程序執(zhí)行的過程中,開啟若干輔助線程進(jìn)行垃圾回收,清理和主線程沒有任何邏輯關(guān)系的內(nèi)存。

          內(nèi)存泄露場景

          全局變量

          // exm1 function Example(){     exm = 'LeBron'    }  // exm2 function Example(){     this.exm = 'LeBron' } Example()

          未清除的定時器

          const timer = setInterval(() => {     //... }, 1000)  // clearInterval(timer)

          閉包

          function debounce(fn, time) {   let timeout = null;    return function () {     if (timeout) {       clearTimeout(timeout);     }      timeout = setTimeout(() => {       fn.apply(this, arguments);     }, time);   }; }  const fn = debounce(handler, 1000); // fn引用了timeout

          未清除的DOM元素引用

          const element = {     // 此處引用了DOM元素     button:document.getElementById('LeBron'),     select:document.getElementById('select') }  document.body.removeChild(document.getElementById('LeBron'))

          如何檢測內(nèi)存泄漏

          這個其實不難,瀏覽器原帶的開發(fā)者工具Performance就可以

          • 步驟
            • F12打開開發(fā)者工具
            • 選擇Performance工具欄
            • 勾選屏幕截圖和Memory
            • 點擊開始錄制
            • 一段時間之后結(jié)束錄制
          • 結(jié)果
            • 堆內(nèi)存會周期性地分配和釋放
            • 如果堆內(nèi)存的min值在逐漸上升則存在內(nèi)存泄漏

          javascript有g(shù)c嗎

          優(yōu)化內(nèi)存使用

          1、盡量不在for循環(huán)中定義函數(shù)

          // exm const fn = (idx) => {     return idx * 2; }  function Example(){     for(let i=0;i<1000;i++){         //const fn = (idx) => {         //    return idx * 2;         // }         const res = fn(i);     } }

          2、盡量不在for循環(huán)中定義對象

          function Example() {   const obj = {};   let res = "";   for (let i = 0; i < 1000; i++) {     // const obj = {     //   a: i,     //   b: i * 2,     //   c: i * 3,     // };     obj.a = i;     obj.b = i * 2;     obj.c = i * 3;     res += JSON.stringify(obj);   }   return res }

          3、清空數(shù)組

          arr = [0, 1, 2] arr.length = 0; // 清空了數(shù)組,數(shù)組類型不變 // arr = []  // 重新申請了一塊空數(shù)組對象內(nèi)存

          【推薦學(xué)習(xí):javascript高級教程】

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號