• 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能发现并解决问题。


     

     

  • 相关阅读:
    辨析六种单例模式
    理解模板模式
    常用DOM API总结
    自我剖析——一天的效率
    对两个数组合并,并去重
    Qt 创建一个QtDesinger第三方控件
    Qt中QComboBox中自定义界面使用stylesheet实现下拉按钮独立效果
    内核对象 windows操作系统
    python之基本内容
    python之总体理解
  • 原文地址:https://www.cnblogs.com/llguanli/p/8330992.html
Copyright © 2020-2023  润新知