我有一個SVG映射和一個輪詢數據更改的時間間隔,並相應地更新地圖上的顏色。這一切都工作正常,除非我使用過渡淡入新的顏色。然後,標籤緩慢地消耗越來越多的內存,直到它崩潰。重複應用d3轉換造成的內存泄漏
我做了一個簡化的例子,顯示了相同的行爲:
var size = 500;
var num = 25;
var boxSize = size/num;
function color(d) {
return '#' + Math.random().toString(16).slice(2,8);
}
var svg = d3.select('body')
.append("svg")
.attr("width", size)
.attr("height", size);
var squares = svg.selectAll(".square")
.data(d3.range(num * num))
.enter().append("rect")
.attr("class", "square")
.attr("width", boxSize)
.attr("height", boxSize)
.attr("x", function (d) { return boxSize * (d % num);})
.attr("y", function (d) { return boxSize * Math.floor(d/num); })
.style("fill", color);
function shuffleColors() {
squares.interrupt().transition().duration(500).style("fill", color);
timer = setTimeout(shuffleColors, 1000);
}
var timer = setTimeout(shuffleColors, 1000);
我在鉻(49)和在Linux火狐(45)嘗試過。前者似乎更快速地爆炸,但這兩者都是問題。它在內存分析器中都沒有出現,但關於:內存顯示了標籤的增長。
我從文檔中得到的理解是,向選擇中添加一個轉換可以用相同的名稱替換之前的任何轉換(包括空名稱),但是我的假設是實現轉換所創建的函數實際上並未拋出出。但我沒有設法讓他們確認或解決這個問題。
於是,一個問題兩個部分:
- 那是一個正確使用D3轉變的,或者是有做什麼我要爲一個比較正確的做法?
- 如果我正確使用了轉換,我該如何才能停止內存泄漏?
編輯:
- 每從Blindman67的評論,我改變了它使用setTimeout和略小。我試圖模擬的原始尺寸越來越小,但需要幾個小時才能確定地變大,所以我試圖加快速度。這個版本似乎還在增長,至少對我而言,Chromium是如此。
- 我看到
d3_selectionPrototype.transition
每增加一個ID就會產生一個新的d3_transition
,但如果舊的垃圾收集器沒有問題的話,那很好。而且我仍然無法指出是否保留它。
我剛剛在您的shuffle Colors函數中添加了一個調試器關鍵字,並將其關聯到D3代碼中。它在呼叫中斷上做的第一件事是開始建立一個1600箇中斷列表,它將每個方塊作爲一個單獨的實體處理。我沒有深入,因爲問題是顯而易見的,你正在大塊地咀嚼記憶,當GC開始放慢速度時,會將setInterval放出,一旦發生這種情況,你只是在等待崩潰。使用setTimeout並在完成後開始下一個洗牌。不會泄漏你的內存溢出你的調用堆棧 – Blindman67
我只是想說'interrupt()'相同。 –
[使用d3轉換導致內存泄漏]可能的重複(https://stackoverflow.com/questions/26735417/using-d3-transitions-causes-memory-leak) – Fraser