久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      完全掌握JavaScript內(nèi)存泄漏(圖文詳解)

      本篇文章給大家?guī)砹岁P于JavaScript中內(nèi)存泄露的相關知識,其中包括內(nèi)存泄露是什么,那些情況會引起內(nèi)存泄露等相關問題,希望對大家有幫助。

      完全掌握JavaScript內(nèi)存泄漏(圖文詳解)

      js 內(nèi)存泄漏

      什么是內(nèi)存泄漏?

      程序的運行需要內(nèi)存。只要程序提出要求,操作系統(tǒng)或者運行時(runtime)就必須供給內(nèi)存。

      對于持續(xù)運行的服務進程(daemon),必須及時釋放不再用到的內(nèi)存。否則,內(nèi)存占用越來越高,輕則影響系統(tǒng)性能,重則導致進程崩潰。
      完全掌握JavaScript內(nèi)存泄漏(圖文詳解)
      不再用到的內(nèi)存,沒有及時釋放,就叫做內(nèi)存泄漏(memory leak)。

      有些語言(比如 C 語言)必須手動釋放內(nèi)存,程序員負責內(nèi)存管理。

      char * buffer;buffer = (char*) malloc(42);// Do something with bufferfree(buffer);

      上面是 C 語言代碼,malloc方法用來申請內(nèi)存,使用完畢之后,必須自己用free方法釋放內(nèi)存。

      這很麻煩,所以大多數(shù)語言提供自動內(nèi)存管理,減輕程序員的負擔,這被稱為"垃圾回收機制"(garbage collector)。

      雖然前端有垃圾回收機制,但當某塊無用的內(nèi)存,卻無法被垃圾回收機制認為是垃圾時,也就發(fā)生內(nèi)存泄漏了。

      哪些情況會引起內(nèi)存泄漏

      1. 意外的全局變量

      全局變量的生命周期最長,直到頁面關閉前,它都存活著,所以全局變量上的內(nèi)存一直都不會被回收。

      當全局變量使用不當,沒有及時回收(手動賦值 null),或者拼寫錯誤等將某個變量掛載到全局變量時,也就發(fā)生內(nèi)存泄漏了。

      2. 遺忘的定時器
      setTimeout 和 setInterval 是由瀏覽器專門線程來維護它的生命周期,所以當在某個頁面使用了定時器,當該頁面銷毀時,沒有手動去釋放清理這些定時器的話,那么這些定時器還是存活著的。

      也就是說,定時器的生命周期并不掛靠在頁面上,所以當在當前頁面的 js 里通過定時器注冊了某個回調(diào)函數(shù),而該回調(diào)函數(shù)內(nèi)又持有當前頁面某個變量或某些 DOM 元素時,就會導致即使頁面銷毀了,由于定時器持有該頁面部分引用而造成頁面無法正常被回收,從而導致內(nèi)存泄漏了。

      如果此時再次打開同個頁面,內(nèi)存中其實是有雙份頁面數(shù)據(jù)的,如果多次關閉、打開,那么內(nèi)存泄漏會越來越嚴重。而且這種場景很容易出現(xiàn),因為使用定時器的人很容易遺忘清除。

      3. 使用不當?shù)拈]包
      函數(shù)本身會持有它定義時所在的詞法環(huán)境的引用,但通常情況下,使用完函數(shù)后,該函數(shù)所申請的內(nèi)存都會被回收了。

      但當函數(shù)內(nèi)再返回一個函數(shù)時,由于返回的函數(shù)持有外部函數(shù)的詞法環(huán)境,而返回的函數(shù)又被其他生命周期東西所持有,導致外部函數(shù)雖然執(zhí)行完了,但內(nèi)存卻無法被回收。

      4. 遺漏的 DOM 元素
      DOM 元素的生命周期正常是取決于是否掛載在 DOM 樹上,當從 DOM 樹上移除時,也就可以被銷毀回收了
      但如果某個 DOM 元素,在 js 中也持有它的引用時,那么它的生命周期就由 js 和是否在 DOM 樹上兩者決定了,記得移除時,兩個地方都需要去清理才能正?;厥账?。

      5. 網(wǎng)絡回調(diào)
      某些場景中,在某個頁面發(fā)起網(wǎng)絡請求,并注冊一個回調(diào),且回調(diào)函數(shù)內(nèi)持有該頁面某些內(nèi)容,那么,當該頁面銷毀時,應該注銷網(wǎng)絡的回調(diào),否則,因為網(wǎng)絡持有頁面部分內(nèi)容,也會導致頁面部分內(nèi)容無法被回收。


      如何監(jiān)控內(nèi)存泄漏

      內(nèi)存泄漏是可以分成兩類的,一種是比較嚴重的,泄漏的就一直回收不回來了,另一種嚴重程度稍微輕點,就是沒有及時清理導致的內(nèi)存泄漏,一段時間后還是可以被清理掉。

      不管哪一種,利用開發(fā)者工具抓到的內(nèi)存圖,應該都會看到一段時間內(nèi),內(nèi)存占用不斷的直線式下降,這是因為不斷發(fā)生 GC,也就是垃圾回收導致的。

      內(nèi)存不足會造成不斷 GC,而 GC 時是會阻塞主線程的,所以會影響到頁面性能,造成卡頓,所以內(nèi)存泄漏問題還是需要關注的。

      場景一:在某個函數(shù)內(nèi)申請一塊內(nèi)存,然后該函數(shù)在短時間內(nèi)不斷被調(diào)用

      // 點擊按鈕,就執(zhí)行一次函數(shù),申請一塊內(nèi)存startBtn.addEventListener("click", function() { 	var a = new Array(100000).fill(1); 	var b = new Array(20000).fill(1);});

      完全掌握JavaScript內(nèi)存泄漏(圖文詳解)

      一個頁面能夠使用的內(nèi)存是有限的,當內(nèi)存不足時,就會觸發(fā)垃圾回收機制去回收沒用的內(nèi)存。

      而在函數(shù)內(nèi)部使用的變量都是局部變量,函數(shù)執(zhí)行完畢,這塊內(nèi)存就沒用可以被回收了。

      所以當我們短時間內(nèi)不斷調(diào)用該函數(shù)時,可以發(fā)現(xiàn),函數(shù)執(zhí)行時,發(fā)現(xiàn)內(nèi)存不足,垃圾回收機制工作,回收上一個函數(shù)申請的內(nèi)存,因為上個函數(shù)已經(jīng)執(zhí)行結束了,內(nèi)存無用可被回收了。

      所以圖中呈現(xiàn)內(nèi)存使用量的圖表就是一條橫線過去,中間出現(xiàn)多處豎線,其實就是表示內(nèi)存清空,再申請,清空再申請,每個豎線的位置就是垃圾回收機制工作以及函數(shù)執(zhí)行又申請的時機。

      場景二:在某個函數(shù)內(nèi)申請一塊內(nèi)存,然后該函數(shù)在短時間內(nèi)不斷被調(diào)用,但每次申請的內(nèi)存,有一部分被外部持有。

      // 點擊按鈕,就執(zhí)行一次函數(shù),申請一塊內(nèi)存var arr = [];startBtn.addEventListener("click", function() { 	var a = new Array(100000).fill(1); 	var b = new Array(20000).fill(1);     arr.push(b);});

      完全掌握JavaScript內(nèi)存泄漏(圖文詳解)

      看一下跟第一張圖片有什么區(qū)別?

      不再是一條橫線了吧,而且橫線中的每個豎線的底部也不是同一水平了吧。

      其實這就是內(nèi)存泄漏了。

      我們在函數(shù)內(nèi)申請了兩個數(shù)組內(nèi)存,但其中有個數(shù)組卻被外部持有,那么,即使每次函數(shù)執(zhí)行完,這部分被外部持有的數(shù)組內(nèi)存也依舊回收不了,所以每次只能回收一部分內(nèi)存。

      這樣一來,當函數(shù)調(diào)用次數(shù)增多時,沒法回收的內(nèi)存就越多,內(nèi)存泄漏的也就越多,導致內(nèi)存使用量一直在增長
      另外,也可以使用 performance monitor 工具,在開發(fā)者工具里找到

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