2011-09-16 25 views
0

我一直在使用加載Google Map的Web應用程序遇到Javascript內存不足錯誤,並且從一個點到另一個點不斷移動。它耗盡了大約半天的時間,但我真的很喜歡它持續很久。我 已經確定,使用map.panTo方法時發生內存泄漏,雖然 我非常懷疑它可能是我使用它的方式(Javascript不是我的強 套裝)。你可以看看這段代碼,並幫我解決這個內存泄漏問題嗎?在調試過程中,爲了保證時間的長短,我加快了它在此演示代碼中的時間間隔(即使通過檢查Windows任務管理器中的進程,泄漏也是顯而易見的)。這運行ASP.Net 3.5 Web窗體,但沒有回發,代碼完全是HTML,CSS和Javascript。它泄漏IE中最糟糕的(這是我需要用來顯示這個)。使用Google地圖的Map.panTo()方法導致Javascript內存泄漏

編輯:

  1. 我已經使用不同版本的谷歌地圖API(2,3.0和3.6)的嘗試。
  2. 我知道我不需要將示例代碼中的映射放入Hashtable或Array中,但不會影響內存泄漏。
  3. 我試圖避免黑客入侵,比如每隔一段時間刷新頁面或使用靜態Google Maps API。
  4. 賞金會去找誰如何解決內存泄漏或誰明確識別和證明爲什麼它不能被修復(如果是這樣的話)。

代碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head id="Head1" runat="server"> 
    <title>Map Shifter</title> 
    <style type="text/css"> 
     #divMap { height: 400px; width:400px; position:absolute; top:10%; left:10%; border: 2px solid #ff1100; }  
    </style> 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?v=2&sensor=false"></script> 
    <script type="text/javascript" language="javascript"> 
     //Have tried both HashTable and Array (Both Leak)... 
     var m_arrMaps = new HashTable(); //new Array(); 
     var m_Timer; 
     function HashTable() { 
      return this; 
     } 
     function LoadMapAndStartShifting() { 
      var objMapCenterPoint = new google.maps.LatLng(20.5, -156); 
      var objMapOptions = { zoom: 9, center: objMapCenterPoint, mapTypeId: google.maps.MapTypeId.ROADMAP, 
       scaleControl: false, streetViewControl:false, zoomControl: false, mapTypeControl: false, panControl: false 
      } 
      var map = new google.maps.Map(document.getElementById("divMap"), objMapOptions); 
      m_arrMaps["ShiftingMap"] = map; 
      setTimeout("ShiftMap(20.5, -156);", 700); 
     } 
     function ShiftMap(decLat, decLng) { 
      var objLatLong = new google.maps.LatLng(decLat, decLng); 
      //Have tried setCenter instead of preferred panTo and it still leaks! 
      m_arrMaps["ShiftingMap"].panTo(objLatLong); 
      if (decLat == 20.5) { 
       //Leaks... 
       ResetTimer(39, -87); 
      } 
      else { 
       //Still leaks... 
       setTimeout("ShiftMap(20.5, -156);", 700); 
      } 
     } 
     function ResetTimer(decLat, decLng) { 
      m_Timer = setTimeout("ShiftMap(" + decLat + ", " + decLng + ");", 700);  
     }  
    </script> 
</head> 
<body onload="LoadMapAndStartShifting();"> 
    <form id="form1" runat="server"> 
    <div id="divMap"></div> 
    </form> 
</body> 
+0

您正在下載多少兆字節的圖像? – c69

+0

很難證明一個否定(泄漏「無法修復」):-)我已經提交給Google論壇,請參閱下面的更新答案。 –

回答

2

爲什麼你創建的地圖一個哈希表?您可以將其創建爲全局變量。我會驚訝,有什麼區別,但你的評論,「/ /已經嘗試HashTable和數組(兩個泄漏)......」讓我想知道爲什麼你需要一個哈希表或數組。

您還可以通過將選項結構直接傳遞給Map()函數,並將latLng直接傳入panTo()函數來擺脫objMapOptions和objMapCenterPoint變量。

<script type="text/javascript" language="javascript"> 
    var m_Timer, map; 

    function LoadMapAndStartShifting() { 
     map = new google.maps.Map(document.getElementById("divMap"), { zoom: 9, center: new google.maps.LatLng(20.5, -156), mapTypeId: google.maps.MapTypeId.ROADMAP, 
      scaleControl: false, streetViewControl:false, zoomControl: false, mapTypeControl: false, panControl: false 
     }); 
     setTimeout("ShiftMap(20.5, -156);", 700); 
    } 
    function ShiftMap(decLat, decLng) { 
     map.panTo(new google.maps.LatLng(decLat, decLng)); 
     if (decLat == 20.5) { 
      //Leaks... 
      ResetTimer(39, -87); 
     } 
     else { 
      //Still leaks... 
      setTimeout("ShiftMap(20.5, -156);", 700); 
     } 
    } 
    function ResetTimer(decLat, decLng) { 
     m_Timer = setTimeout("ShiftMap(" + decLat + ", " + decLng + ");", 700);  
    }  
</script> 

另一個建議,緩存地圖怎麼樣?我不知道這個示例代碼是否實際上是你在做什麼,但是如果它只是以這種方式在兩個地圖之間滾動,你不能使用靜態地圖api,並緩存圖像,只需使用javascript旋轉圖片?

+0

對於靜態地圖API和緩存建議+1。我希望它不會出現在這一點上(雖然我們設置了標記,並且整個項目比兩點之間切換更加健壯和動態)。刪除散列表並沒有什麼區別(我使用多個映射的原始項目,所以散列表使代碼更清晰)。 – N0Alias

2

看起來你只是在「Hashtable」對象中存儲一個元素 - [「ShiftingMap」] - 它沒有拿着地圖,它拿着一張地圖。您可以使用全局變量來保存地圖對象。

唯一重複分配是爲每個平底鍋創建的new google.maps.LatLng(decLat, decLng)

建議:

1)LatLng的文檔不給任何警告大約需要顯式地釋放對象,所以想必垃圾收集應當予以受理。

2)考慮整體問題 - 您試圖連續使用谷歌地圖6小時或更長時間。你爲什麼認爲漏洞在你的代碼中?這個問題更可能出現在G Maps中。可能下載的地圖圖像切片被保存在本地,因爲用戶可能想要平移。

作爲測試,請嘗試在兩點之間來回切換,而不是在全球範圍內進行當前的平移。 (如果我理解正確的相對移動。)

看看是否泄漏發生在內存/小時的速度

3)一定要看看不同的瀏覽器不同會影響您的問題。 Esp試用Google Chrome。

新增

我重新工作的演示代碼到移動電話的LatLng圈外的,它仍然泄漏。另外,最好在setTimeout調用中使用非字符串值,所以我也改變了這一點。我還使用Maps API tutorial將doctype設置爲他們推薦的內容。

結果在下面。它在FF和Chrome上泄漏。我在官方Google Maps API v3 forum提交了一篇文章。

看來很清楚.panTo方法泄漏。我想你的下一步是看看Google員工是否迴應了這個帖子。

Test case demo

重做測試案例:

<!DOCTYPE html> 
<html> 
<!-- http://sandbox.kluger.com/map_demo.html --> 
<!-- See tutorial http://code.google.com/apis/maps/documentation/javascript/tutorial.html --> 
<head> 
    <title>Map Shifter</title> 
    <style type="text/css"> 
     #divMap { height: 400px; width:400px; position:absolute; top:10%; 
        left:10%; border: 2px solid #ff1100; } 
    </style> 
    <script type="text/javascript" 
      src="http://maps.google.com/maps/api/js?sensor=false"></script> 
    <script type="text/javascript" language="javascript"> 
     // Globals 
     var map, 
      mapCenterPoints, 
      currentPoint; 

     var ShiftMap = function() { 
      currentPoint = currentPoint == 0 ? 1 : 0; // update 
      map.panTo(mapCenterPoints[currentPoint]); 
      setTimeout(ShiftMap, 700);   
     } 

     function LoadMapAndStartShifting() { 
      mapCenterPoints = [new google.maps.LatLng(20.5, -156), 
           new google.maps.LatLng(39, -87)]; 
      currentPoint = 0; 

      var objMapOptions = { zoom: 9, 
            center: mapCenterPoints[currentPoint], 
            mapTypeId: google.maps.MapTypeId.ROADMAP, 
            scaleControl: false, streetViewControl:false, 
            zoomControl: false, mapTypeControl: false, 
            panControl: false 
      } 

      map = new google.maps.Map(document.getElementById("divMap"), 
         objMapOptions); 
      setTimeout(ShiftMap, 700); 
     } 
    </script> 
</head> 
<body onload="LoadMapAndStartShifting();"> 
     <div id="divMap"></div> 
</body> 
</html> 
+0

感謝您的積分!一個Google員工說他正在修復!請參閱http://code.google.com/apis/maps/documentation/javascript/forum.html?place=topic%2Fgoogle-maps-js-api-v3%2Fjzz7gtIH0yA%2Fdiscussion –

2

剛剛有了另一個想法。您指定v = 2,即獲得此API的版本2版本。目前的版本是3.6。建議您嘗試更新版本號(或者只是刪除v參數以獲取最新的穩定版本),然後查看是否改進了這些內容。可能他們已經整理了更新版本的垃圾收集。

+0

我應該提出這個問題我試過這個建議。我會編輯。 – N0Alias