如何用 Chrome 解決內(nèi)存泄漏

如何用 Chrome 解決內(nèi)存泄漏

簡(jiǎn)介

引用自 Google 的描述

  • 頁(yè)面的性能隨著時(shí)間的延長(zhǎng)越來(lái)越差。 這可能是內(nèi)存泄漏的癥狀。 內(nèi)存泄漏是指,頁(yè)面中的錯(cuò)誤導(dǎo)致頁(yè)面隨著時(shí)間的延長(zhǎng)使用的內(nèi)存越來(lái)越多。

  • 頁(yè)面的性能一直很糟糕。 這可能是內(nèi)存膨脹的癥狀。 內(nèi)存膨脹是指,頁(yè)面為達(dá)到最佳速度而使用的內(nèi)存比本應(yīng)使用的內(nèi)存多。

  • 頁(yè)面出現(xiàn)延遲或者經(jīng)常暫停。 這可能是頻繁垃圾回收的癥狀。 垃圾回收是指瀏覽器收回內(nèi)存。 瀏覽器決定何時(shí)進(jìn)行垃圾回收。 回收期間,所有腳本執(zhí)行都將暫停。因此,如果瀏覽器經(jīng)常進(jìn)行垃圾回收,腳本執(zhí)行就會(huì)被頻繁暫停。

舉個(gè)官網(wǎng)的例子

有以下代碼會(huì)導(dǎo)致內(nèi)存泄漏問(wèn)題

loop.js 代碼

    var x = [];
    function grow() {
      x.push(new Array(1000000).join('x'));
    }
    document.getElementById('grow').addEventListener('click', grow);

html 代碼

    <!DOCTYPE html>
    <html>
        <head>
            <title>memory</title>
        </head>
        <body>
            <p>hello,world</p>
            <button id="grow">grow</button>
            <script src="loop.js"></script>
        </body>
    </html>

如何解決

有以下兩個(gè)步驟:

  1. 檢測(cè)網(wǎng)頁(yè)
  2. 找出內(nèi)存泄漏的代碼
  3. 代碼修改

先說(shuō)第一部分:如何檢測(cè)

檢測(cè)

用 Chrome 開(kāi)發(fā)工具進(jìn)行檢測(cè),

  1. 在 Chrome 的 開(kāi)發(fā)者工具 上打開(kāi) Performance 面板。
  2. 點(diǎn)擊 Memory 復(fù)選框。
  3. 按紅色那個(gè) Record 按鈕,進(jìn)行記錄

上圖有兩個(gè)地方需要關(guān)注的,就是下面藍(lán)色的線。藍(lán)色的線的起點(diǎn)不斷增高,意味著有部分內(nèi)存沒(méi)有完全的回收釋放掉,也就是說(shuō)意味著頁(yè)面會(huì)不斷地占越來(lái)越多的內(nèi)存。直至最后 Chrome 奔潰!

接著揪出元兇出來(lái)

如何找出

打開(kāi)預(yù)覽圖,然后找一找,在藍(lán)色線增高的點(diǎn)那里,我們?cè)诰W(wǎng)頁(yè)執(zhí)行了什么的操作。

上圖可看出,點(diǎn)擊了按鈕 grow ,這時(shí)可以直接去 grow 觸發(fā)代碼去觀察的了。

如果還不是很確定的話,可以記錄分配時(shí)間線:

  1. 打開(kāi)開(kāi)發(fā)者工具
  2. 然后轉(zhuǎn)到 Memory 面板,選擇 Record Allocation Timeline 單選按鈕按 Start 按鈕,執(zhí)行您懷疑導(dǎo)致內(nèi)存泄漏的操作。完成后
  3. Stop recording 按鈕

選中增高的藍(lán)色線,下面在 Constructor 里看到最高的 string ,點(diǎn)擊后,看下面。會(huì)觀察到原來(lái)是代碼中的 x 變量沒(méi)有被釋放。

修改代碼

我們看到 grow() 的代碼如下:

    var x = [];
    
    function grow() {
      x.push(new Array(1000000).join('x'));
    }
    
    document.getElementById('grow').addEventListener('click', grow);

grow 執(zhí)行的時(shí)候,會(huì)向 x 插入數(shù)據(jù),而 x 這個(gè)變量則是一個(gè)全局變量(實(shí)際可以說(shuō)是 Window對(duì)象下的屬性),而 x 這個(gè)變量沒(méi)有釋放,就導(dǎo)致不停地增加下去了。

我們來(lái)試一種避免內(nèi)存泄漏的寫(xiě)法,避免使用全局變量。將變量寫(xiě)在函數(shù)里面,當(dāng)函數(shù)執(zhí)行完的時(shí)候 x 變量會(huì)釋放

    function grow() {
      var x = [];
      x.push(new Array(1000000).join('x'));
    }

其它的方式:參考下面這篇文吧:

參考

這篇文大部分都引用 Google 的這篇文, 部分內(nèi)容做出了修改

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容