本文是面試彙總分支——怎麼檢測瀏覽器中的內存泄露。javascript
本文轉自:javascript內存泄露及谷歌瀏覽器查看內存使用java
今天寫一下javascript致使內存泄露的幾種方式,及咱們在平時工做中,如何經過谷歌瀏覽器查看內存使用狀況。我前面的文章製做公司數據大屏的幾點技術總結 ,裏面用到了很多setInterval,setInterval用多了,會佔用大量的內存,要咱們必須及時清理,不然,運行時間一長,極有可能致使瀏覽器崩潰!面試
一、意外的全局變量編程
JavaScript 處理未定義變量的方式比較寬鬆:未定義的變量會在全局對象建立一個新變量。在瀏覽器中,全局對象是 window 。數組
例如:瀏覽器
haorooms ="這是一個全局的haorooms"
實際上生成了一個全局的haorooms,雖然一個簡單的字符串,無傷大雅,也泄露不了多少內存,可是咱們在編程中儘可能少的避免全局變量!數據結構
另一種全局變量可能由this建立。例如:閉包
function foo() { this.variable = "potential accidental global"; } // Foo 調用本身,this 指向了全局對象(window) foo();
二、沒有及時清理的計時器或回調函數ide
本文剛剛開始的時候,我就說了setInterval用多了,會佔用大量的內存。所以setInterval咱們必須及時清理!能夠用以下方式清理setInterval。函數
function b() { var a = setInterval(function() { console.log("Hello"); clearInterval(a); b(); }, 50); } b();
或者用2個函數:
function init() { window.ref = window.setInterval(function() { draw(); }, 50); } function draw() { console.log('Hello'); clearInterval(window.ref); init(); } init();
或者咱們用setTimeout
function time(f, time) { return function walk() { clearTimeout(aeta); var aeta =setTimeout(function () { f(); walk(); }, time); }; } time(updateFormat, 1000)();
三、脫離 DOM 的引用
有時,保存 DOM 節點內部數據結構頗有用。假如你想快速更新表格的幾行內容,把每一行 DOM 存成字典(JSON 鍵值對)或者數組頗有意義。此時,一樣的 DOM 元素存在兩個引用:一個在 DOM 樹中,另外一個在字典中。未來你決定刪除這些行時,須要把兩個引用都清除。
var elements = { button: document.getElementById('button'), image: document.getElementById('image'), text: document.getElementById('text') }; function doStuff() { image.src = 'http://some.url/image'; button.click(); console.log(text.innerHTML); // 更多邏輯 } function removeButton() { // 按鈕是 body 的後代元素 document.body.removeChild(document.getElementById('button')); // 此時,仍舊存在一個全局的 #button 的引用 // elements 字典。button 元素仍舊在內存中,不能被 GC 回收。 }
四、閉包
閉包注意事項我以前說起過,請看文章 http://www.haorooms.com/post/qianduan_xnyhbc
五、echart不停調用致使內存泄露
不停的用setInterval調用echart,更新echart表格及地圖數據,及時清理了setInterval,也會致使內存泄露!
解決辦法:
首先及時清理:
myChart.clear(); myChart.setOption(option);
可是你會發現,做用不大,那麼如何處理呢?
我是以下作的:
第一次處理用
myChart.clear(); myChart.setOption(option);
後面用setInterval的時候,我是以下寫的:
mapCharts.setOption({ series: [{ data: _this.convertData(mapdata) }, { data: _this.convertData(mapdata.sort(function (a, b) { return b.value - a.value; }).slice(1, 6)), }, { data: _this.convertData(mapdata.sort(function (a, b) { return b.value - a.value; }).slice(0, 1)) }] },{notMerge: false, lazyUpdate: false, silent:false});
僅僅從新設置了series裏面的數據,不是所有setOption(option);這樣就不會內存泄露了!
使用 Chrome 任務管理器做爲內存問題調查的起點。 任務管理器是一個實時監視器,能夠告訴您頁面當前正在使用的內存量。
按 Shift+Esc 或者轉到 Chrome 主菜單並選擇 More tools > Task manager,打開任務管理器。
使用 Chrome DevTools 的 Timeline 面板能夠記錄和分析您的應用在運行時的全部活動。 這裏是開始調查應用中可覺察性能問題的最佳位置。
Timeline 面板包含如下四個窗格:
一、Controls。開始記錄,中止記錄和配置記錄期間捕獲的信息。
二、Overview。 頁面性能的高級彙總。
FPS。每秒幀數。綠色豎線越高,FPS 越高。 FPS 圖表上的紅色塊表示長時間幀,極可能會出現卡頓。
CPU。 CPU 資源。此面積圖指示消耗 CPU 資源的事件類型。
NET。每條彩色橫槓表示一種資源。橫槓越長,檢索資源所需的時間越長。 每一個橫槓的淺色部分表示等待時間(從請求資源到第一個字節下載完成的時間)。
三、火焰圖。 CPU 堆疊追蹤的可視化。
您能夠在火焰圖上看到一到三條垂直的虛線。藍線表明 DOMContentLoaded 事件。 綠線表明首次繪製的時間。 紅線表明 load 事件。
深色部分表示傳輸時間(下載第一個和最後一個字節之間的時間)。
橫槓按照如下方式進行彩色編碼:
HTML 文件爲藍色。
腳本爲黃色。
樣式表爲紫色。
媒體文件爲綠色。
其餘資源爲灰色。