zoukankan      html  css  js  c++  java
  • BingMap频繁Add Pushpin和Delete Pushpin会导致内存泄露

            近期在做性能測试的时候发现BingMap内存泄露(memory leak)的问题,查找了一些国外的帖子,发现也有类似的问题,可是没有好的解决的方法。

    https://social.msdn.microsoft.com/Forums/en-US/3226f255-2ae1-4718-b848-5f24e76b64b0/your-pushpins-are-broken-addremove-leads-to-memory-leak?forum=bingmapsajax

            经过一番尝试。找到了一个折中的解决方式,分享一下。

            先贴一下Testing Code吧:

    <!DOCTYPE html>
    <%--<meta http-equiv='x-ua-compatible' content='IE=7;IE=9' />--%>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    	<script src="Scripts/jquery-1.8.3.min.js" type="text/javascript"></script>
    	<script charset="UTF-8" type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div id="myMap" style="800px;height:600px;position:absolute">
    	</div>
    	<input id="btnAdd" type="button" style="position:absolute;top:700px;left:10px;" value="Add" onclick="addBatchPushpin();"/>
    	<input id="btnDelete" type="button" style="position:absolute;top:700px;left:110px;" value="Delete" onclick="deleteBatchPushpin();" />
    	<input id="btnClear" type="button" style="position:absolute;top:700px;left:210px;" value="Clear" onclick="clearPushpin();"/>
    	<input id="Button1" type="button" style="position:absolute;top:700px;left:310px;" value="Find" onclick="findPushpin();"/>
    
    	<div id="hidElement"></div>
        </form>
    </body>
    </html>
    <script type="text/javascript" >
    	var map = null;
    	var _layer = null;
    	var _bingMapKey = "ApirbCqPCAM1bVBVeh5CrrNm-7lzdCkbDT5OPkck8pXXeKWWGNUrIGsTqlkDHlu8";
    	$(document).ready(function ()
    	{
    		var mapOptions = {
    			credentials: _bingMapKey,
    			enableClickableLogo: false,
    			enableSearchLogo: false,
    			showMapTypeSelector: true,
    			showCopyright: false
    		}
    		map = new Microsoft.Maps.Map($("#myMap")[0], mapOptions);
    		var infoboxLayer = new Microsoft.Maps.EntityCollection();
    		map.entities.push(infoboxLayer);
    		map.setView({ animate: true, zoom: 5, center: new Microsoft.Maps.Location(40, -71) });
    
    		_layer = new Microsoft.Maps.EntityCollection();
    		map.entities.push(_layer);
    
    		//var lat = 40.56090348161442;
    		//var lon = -74.345836486816438;
    		//addPushpin(lat,lon);
    
    		setInterval(addBatchPushpin, 500);
    		setInterval(deleteBatchPushpin, 1000);
    	})
    
    	function addBatchPushpin()
    	{
    		var lat = 40.56090348161442;
    		var lon = -74.345836486816438;
    		for (var i = 0; i < 20; i++)
    		{
    			var randomLatitude = Math.random() + lat;
    			var randomLongitude = Math.random() + lon;
    
    			addPushpin(randomLatitude, randomLongitude);
    		}
    	}
    
    	function deleteBatchPushpin()
    	{
    		var len = _layer.getLength();
    		for (var i = 0; i < len; i++)
    		{
    			_layer.removeAt(0);
    			$('#cfsNew').remove();
    			window.CollectGarbage();
    		}
    	}
    
    	function addPushpin(lat, lon)
    	{
    		var htmlTest = '<table id="cfsNew" cellpadding="0" cellspacing="0"><tr><td><div style="border: black 2px solid; padding-bottom: 0em; line-height: 12px; background-color: white; margin: 0em;padding-left: 0px; padding-right: 0px; font-family: Arial; color: black;font-size: 12px; font-weight: bold;padding-top: 0em;"><div style="white-space: nowrap;">{P2012-001093} </div><div style="font-weight: bold; font-size: 12px; font-family:Arial"><table style="font-size:inherit;" cellpadding="0" cellspacing="0"><tr><td style=" 5px; height:5px;"><div style=" background-color: rgb(0,128,0);  5px;display: block; margin-bottom: 2px; height: 6px; overflow: hidden; margin-right: 1px"> </div></td><td style="color: rgb(0,128,0);font-size: 12px; font-family:Arial; font-weight:bold;">{297}</td></tr><tr><td style=" 5px;"><div style=" background-color: rgb(0,128,0);  5px;display: block; margin-bottom: 2px; height: 6px; overflow: hidden; margin-right: 1px"></div></td><td style="color: rgb(0,128,0);font-size: 12px; font-family:Arial; font-weight:bold;">907</td></tr><tr><td style=" 5px;"><div style=" background-color: rgb(255,0,0);  5px;display: block; margin-bottom: 4px; height: 6px; overflow: hidden; margin-right: 1px"></div></td><td style="color: rgb(0,128,0);font-size: 12px; font-family:Arial; font-weight:bold;">401</td></tr><tr><td style=" 5px;"><div style=" background-color: rgb(0,0,220);  5px;display: block; margin-bottom: 4px; height: 6px; overflow: hidden; margin-right: 1px"></div></td><td style="color: rgb(0,128,0);font-size: 12px; font-family:Arial; font-weight:bold;">408</td></tr></table></div></div></td></tr><tr><td align="center"><div align="center"><img style="position:relative;  40px; height: 40px; left: 20px;top:-1px;" src="Images/ReOpened Box.png" />                    <img style="position:relative;  35px; height: 35px; left: -21px; top: -1px;" src="Images/pin.png" /></div></td></tr></table>';
    		var loc = new Microsoft.Maps.Location(lat, lon);
    		var html = htmlTest;
    
    		var pushpinOptions = { htmlContent: html, zIndex: 100000,  getWidth(html) };
    		var pushpin = new Microsoft.Maps.Pushpin(loc, pushpinOptions);
    		_layer.push(pushpin);
    	}
    
    	function clearPushpin()
    	{
    		_layer.clear();
    		window.CollectGarbage();
    	}
    
    	function findPushpin()
    	{
    		var test = $('#cfsNew').length;
    		alert(test);
    	}
    	
    	function getWidth(html)
    	{
    		element = $("#hidElement");
    		element.html(html);
    		var height = element[0].scrollHeight;
    		var width = element.children().width();
    		return width;
    	}
    
    </script>

            分析一下详细的原因吧,就是往地图上添加pushpin的时候,实际上是添加了一个HTML元素。可是移除的时候仅仅是调用_layre.remove(pushpin)或者_layer.removeAt(index)。这两个方法是一样的效果,仅仅是从BingMap的EntityCollection集合中移除了Pushpin对象。可是Pushpin的HTML对象在内存中依旧存在,所以频繁添加移除会导致内存不断的增长。

            測试结果:

    1. 将cfsNew的HTML元素直接放到页面上,然后每次通过取DOM元素的方式取去加入到地图上。内存增长的速度大概是每秒10M。

    2. 将cfsNew的HTML写成一个var的字符串的形式赋给Pushpin的contentHTML上,内存增长的速度大概每秒1M。

    3. 假设不用HTML格式的Pushpin。用默认的Pushpin的图标(水滴状),内存添加的频率为每秒0.1M。

    4. 加入了$('#cfsNew').remove();方法之后,内存持续添加的情况消失了。

            眼下我仅仅是通过删除是手动移除HTML对象的方式解决问题,只是因为每一个图标的HTML是不一样的。还须要绑定特别的属性做这种标记。给程序开发添加了非常大的不方便,还是希望Microsoft能发现并解决问题。


     

     

  • 相关阅读:
    Visifire正式版(v1.1)发布
    [转]PSP机能强大!已能模拟运行WINDOWS系统?
    在Silverlight+WCF中应用以角色为基础的安全模式(一)基础篇之角色为基础的安全模式简介 Virus
    C#的加密解密算法,包括Silverlight的MD5算法 Virus
    MMORPG programming in Silverlight Tutorial (10)Implement the sprite’s 2D animation (Part IV)
    Game Script: Rescue Bill Gates
    MMORPG programming in Silverlight Tutorial (9)KeyFrame Animation
    MMORPG programming in Silverlight Tutorial (5)Implement the sprite’s 2D animation (Part II)
    MMORPG programming in Silverlight Tutorial (7)Perfect animation
    MMORPG programming in Silverlight Tutorial (3)Animate the object (Part III)
  • 原文地址:https://www.cnblogs.com/llguanli/p/8330992.html
Copyright © 2011-2022 走看看