2011-07-19 33 views
2

我已經花了幾天時間,並從我能想到的每個角度打它。我正在研究一個簡單的Windows 7小工具。該腳本將從遠程Web服務器提取JSON數據並將其放在頁面上。我爲$ .getJSON使用jQuery 1.6.2。腳本在每個循環中消耗更多內存。從WEB拉JSON時的內存泄漏

var count = 1; 

$(document).ready(function() { 
    updateView(); 
}); 

function updateView(){ 
    $("#junk").html(count); 
    count++; 
    $.getJSON(URL + "&callback=?", populateView); 
    setTimeout(updateView, 1000); 
} 

function populateView(status) { 
    $("#debug").html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total"); 
} 

任何幫助將不勝感激....謝謝!

編輯:添加JSON數據樣本

?({"queue":{"active_lang":"en","paused":true,"session":"39ad74939e89e6408f98998adfbae1e2","restart_req":false,"power_options":true,"slots":[{"status":"Queued","index":0,"eta":"unknown","missing":0,"avg_age":"2d","script":"None","msgid":"","verbosity":"","mb":"8949.88","sizeleft":"976 MB","filename":"TestFile#1","priority":"Normal","cat":"*","mbleft":"975.75","timeleft":"0:00:00","percentage":"89","nzo_id":"-n3c6z","unpackopts":"3","size":"8.7 GB"}],"speed":"0 ","helpuri":"","size":"8.7 GB","uptime":"2d","refresh_rate":"","limit":0,"isverbose":false,"start":0,"version":"0.6.5","new_rel_url":"","diskspacetotal2":"931.51","color_scheme":"gold","diskspacetotal1":"931.51","nt":true,"status":"Paused","last_warning":"","have_warnings":"0","cache_art":"0","sizeleft":"976 MB","finishaction":null,"paused_all":false,"cache_size":"0 B","finish":0,"new_release":"","pause_int":"0","mbleft":"975.75","diskspace1":"668.52","scripts":[],"categories":["*"],"darwin":false,"timeleft":"0:00:00","mb":"8949.88","noofslots":1,"nbDetails":false,"eta":"unknown","quota":"","loadavg":"","cache_max":"0","kbpersec":"0.00","speedlimit":"","webdir":"","queue_details":"0","diskspace2":"668.52"}}) 

編輯2:剝離下來的代碼本,它仍然泄漏。我認爲這消除了穿越DOM作爲貢獻者。

$(document).ready(function() { 
    setInterval(updateView, 1000); 
}); 

function updateView(){ 
    $.getJSON(URL + "&callback=?", populateView); 
} 

function populateView(status) { 
} 

編輯3:這不是jQuery的。我刪除了jQuery,並用直接的js做到了。仍然泄漏。

function init(){ 
    setInterval(updateView, 1000); 
} 

function updateView(){ 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", URL, false); 
    xhr.setRequestHeader("If-Modified-Since", "0"); 
    xhr.send(''); 
} 

所以...如果它不是jQuery,不只是在IE中(Chrome也是如此)。有沒有搞錯?!想法?

謝謝!

+1

你能把小提琴放在jsfiddle.net上嗎?這會給你一個我們可以看到的可以證明的例子。 –

+0

另外,我們在這裏討論的內存有多少? –

+0

該頁面還在發生什麼?什麼是「狀態」變量? – Pointy

回答

2

編輯2:

如果它實際上是任務管理器在此處出現泄漏,那麼我認爲下一步是調查IE瀏覽器,因爲我相信,IE瀏覽器,然後使用託管的Windows小工具引擎。

如果你能在一個小的HTML文件重新創建腳本,您可以運行此工具,看看它是否IE是在做它:

http://blogs.msdn.com/b/gpde/archive/2009/08/03/javascript-memory-leak-detector-v2.aspx

而且,你運行IE8或9?


編輯:

基於在OP JSON字符串;基本上這個問題在這裏是誤導。 發佈的JavaScript位工作得很好。

生成JSON的服務器是顯示內存使用情況差異的服務器,我會調查創建該JSON並查看問題所在的網站/端點。


只是有一個想法,

$ .getJSON僅僅是jQuery的$就調用一個速記功能。

我不知道,如果你改變你的代碼使用$阿賈克斯而是專門添加了緩存機制,它它使不同:

$.ajax({ 
    url: URL + "&callback=?", 
    dataType: 'json', 
    cache: false, 
    success: populateView 
}); 

這可能會阻止它試圖將其存儲在內存中也許和取決於你的瀏覽器,它可能會顯示更多的內存,因爲你只是沒有收集垃圾,可以這麼說。

+0

沒有幫助...仍然泄漏約5-10K每秒 – T3chDad

+0

否...客戶端是什麼顯示內存泄漏js內存消耗每次輪詢服務器時都會增加JSON – T3chDad

+0

客戶端正在顯示它,但不是它會根據queue.buffer和queue.mb的值進行計算? –

2

我有這樣的感覺,updateView中的setTimeout函數導致了這種行爲。爲了驗證這一點,你可以修改你的代碼:

$(document).ready(function() { 
    setInterval(updateView, 1000); 
}); 

function updateView(){ 
    $("#junk").html(count); 
    count++; 
    $.getJSON(URL + "&callback=?", populateView); 
} 

function populateView(status) { 
    $("#debug").html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total"); 
} 

編輯:setInterval函數將執行功能一遍遍每x毫秒的通過。 Here給文檔。

編輯2: 另一個性能鬆動(雖然它可能不是關鍵問題)是,你每秒都在遍歷DOM來找到$('#debug')元素。你可以存儲和傳遞爲:

 $(document).ready(function() { 
      var debug = $('#debug'); 
      var junk = $('#junk')   ; 
      setInterval(function(){updateView(debug, junk)}, 1000); 

     }); 

     function updateView(debug, junk){ 
      junk.html(count); 
      count++; 
      $.getJSON(URL + "&callback=?", function(status){populateView(status,debug)}); 
     } 

     function populateView(status) { 
      debug.html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total"); 
     } 

編輯3:我已經改變了上面的代碼,因爲我忘了採取從服務器的響應。假設queue是返回的JSON的屬性,那麼代碼應如上所述。

編輯4:這是一個非常有趣的問題。那麼另一種方法。讓我們假設,仍然有一些客戶端腳本堵塞了內存。這可能是什麼?據我所知只剩下兩件事是setInterval和$ .getJSON函數。 $ .getJSON函數是一個簡單的ajax請求包裝器,它會觸發請求並等待來自服務器的響應。 setInterval函數有點奇怪,因爲它會設置定時器,消息函數等。

我想如果你設法在你的服務器上模擬這個,或者甚至只是在你的瀏覽器中刷新這個網頁每秒/ 5秒你將能夠看到它是處理你的請求的客戶端還是服務器。

+0

沒有幫助...仍然泄漏約300K /分鐘。 – T3chDad

+0

@ T3chDad,如果你增加5秒的時間間隔。原因是,如果每秒都有jQuery遍歷DOM的內存消耗,它就會顯示出來。我將添加另一個編輯,以便查看。 – sTodorov

+0

此status.queue數據是由您的特定JSON對象返回的數據嗎?如果是這樣,那麼你正在測量錯誤的東西,返回的內存就是創建JSON的內存。你能分享網址嗎? –

0

發現此線程試圖找到這個問題的根本原因,因爲我最近也有類似的問題,雖然我的記憶會增加約每分鐘1Mb ...我幾乎將它隔離到json解析。運行類型爲'text'的ajax命令,您應該看到內存得到清理。

我發現一個庫json_parse.js遞歸解析使用JS引擎(而不是eval)的json數據。我在成功回調中手動將文本數據解析爲json,這很有效。

+0

對不起,意思是dataType:'text' – Itamar