2011-10-05 56 views
10

在我的Google Maps v3應用程序中,我正在創建標記並將其放置在地圖上。對於每一個,我在'點擊'中添加一個事件監聽器,這樣當用戶點擊它們時我就可以顯示一個信息窗口。在Google Maps v3中,從內存中刪除標記是否會自動殺死任何聽衆?

我將我的標記保存在一個javascript數組中,並使用.setMap()在地圖上顯示/隱藏它們。有些情況下用戶希望他們從地圖上刪除。在這種情況下,我做marker.setMap(null),然後從我的數組中刪除標記。

是否建議在標記上保留事件偵聽器數組,以便在刪除標記時刪除這些事件偵聽器?或者當事件偵聽器的偵聽對象從內存中刪除時,它會從內存中刪除嗎?

從最終用戶的角度來看,我不認爲這樣做很重要,但我很好奇,如果事件偵聽器仍然存在某處,即使我刪除了標記。我希望儘可能保持整潔。

回答

12

我不確定聽衆是否被刪除,但我的猜測不是。我的猜測是,由於監聽者仍然在監聽,即使你不再引用該對象,監聽者也會這樣做,因此它將保留在內存中。你並不需要保持對偵聽器的引用,你可以調用

google.maps.event.clearInstanceListeners(marker); 

清除所有聽衆您從數組中刪除它。

1

據我所知,聽衆被從內存中刪除。

從理論上講,這可能是因爲聽衆不會主動聽取 - 谷歌地圖只會將它們存儲在相關的功能中,然後詢問該功能在觸發事件時具有哪些聽衆。

實際上,我跑的測試,並且這些結果如下:在JS

Tabs 1 and 2 create a point with 20000 listeners, and track the listeners. 
Tab 3 creates a point with 20000 listeners, but doesn't track them. 
Stage 1 is after they've got the listeners. 
Stage 2 is after they've dropped something (tab 1: point, 2: listeners, 3: point) 
Stage 3 is after they've dropped the other (tab 1: listeners, 2: point, 3: no change (listeners dropped implicitly at stage 2)) 
Tab  PID  Memory (live, K) at stage... 
       1  2  3 
1  4643 18194 16026 8265 
2  4659 18174 8155 8227 
3  4676 17750 8152 8202

內存使用情況是荒謬很難跟蹤,部分(I懷疑),因爲自動垃圾收集器的。爲了得到這些結果,我使用了chrome內置的任務管理器,並且在實驗的每個主要步驟之後,循環大量內存,然後停止使用以強制垃圾收集器的手。

這裏的一個好奇是,當標籤1掉落點時,它丟失了大約2000K的內存,而當標籤2下降時,它增加77K(考慮到內存使用的波動性,可以忽略不計)。我懷疑這是因爲標籤1下降了一個點與20000聽衆附加,而標籤2下降一個裸點。

這是我使用的源代碼。我不提供小提琴鏈接,因爲小提琴只是使跟蹤內存使用更加困難:/

HTML(插入自己的API密鑰):

<!DOCTYPE html> 
<html> 
     <head> 
       <style type="text/css"> 
         html, body {height: 100%; width: 100%;} 
         #map {width: 100%; height: 80%;} 
       </style> 
     </head> 
     <body> 
<h1>Welcome to MapLand, home of a single map.</h1> 
<div id="map"></div> 
<button onclick="addPts(true);">add points (store listeners)</button> 
<button onclick="addPts(false);">add points (don't store listeners)</button> 
-------- 
<button onclick="deletePts();">delete points</button> 
<button onclick="deleteLs();">delete listeners</button> 
-------- 
<button onclick="checkListenerVar();">check listener var</button> 
<button onclick="cycleLargeChunk();">cycle large chunk</button> 
     </body> 
     <script src="test2.js"></script> 
     <script async src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAorBo-zMFJo9viqdv3pkuhMyg5hytpbaQ&callback=initMap"></script> 
</html> 

JS(test2.js):

var uluru = {lat: -25.363, lng: 131.044}; 
var map; 
function initMap() { 
     map = new google.maps.Map(document.getElementById('map'), { 
       zoom: 4, 
       center: uluru 
     }); 
} 
var ptLat = uluru.lat, ptLng = uluru.lng; 
var pts = []; // points 
var ls = []; // listeners 
var listenerVar; 
function addPts(storeLs) { 
     var m = new google.maps.Marker({ 
       position: {lat: ptLat, lng: ptLng}, 
       map: map 
     }); 
     ptLng += 1; 
     if (ptLng > uluru.lng + 20) { 
       ptLng = uluru.lng; 
       ptLat += 1; 
     } 
     pts.push(m); 
     for (var i = 50000; i > 0; i--) { 
       var l = google.maps.event.addListener(m, 'click', function() {listenerVar = i;}); 
       if (storeLs) ls.push(l); 
     } 
} 
function deletePts() { 
     for (var i = pts.length-1; i >= 0; i--) pts[i].setMap(null); 
     pts = []; 
     ptLat = uluru.lat; 
     ptLng = uluru.lng; 
} 
function deleteLs() { 
     for (var i = ls.length-1; i >= 0; i--) ls[i].remove(); 
     ls = []; 
} 
function checkListenerVar() { 
     alert("Listener var is " + listenerVar + ", but is being reset to -1."); 
     listenerVar = -1; 
} 
function cycleLargeChunk() { 
     var l = [0]; 
     for (var i = 0; i < 26; i++) { 
       l = l.concat(l); 
     } 
     //Force the environment to hang on to l for at least a second. 
     setTimeout(function() {console.log(l.length);}, 1000); 
} 
相關問題