Bing Maps V8 JS API 内存泄漏问题
Bing Maps V8 JS API Memory Leak Issues
概述: 我一直在处理的这个项目从外部源接收消息并根据收到的信息更新 Bing 地图。但是,当我让页面 运行 长时间运行时,页面最终会耗尽所有内存并自行崩溃。
细节: 这个 memory issue 在我从 Google 地图切换到 Bing 地图后出现,我无法解决无论我尝试过什么。我进行了全面搜索,试图通过 Bing 地图最佳做法解决此问题,或者至少找到导致此问题的原因,但我一直无法找到真正解决问题的任何方法。
我有大量 detached DOMs 并尝试使用 Google Chrome 的控制台更仔细地分析它们,但没有成功。
尝试的修复:
- 将与添加处理程序有关的所有事情都移到地图初始化函数中(如下所示),但这似乎并没有太大改善。
- 正在从地图初始化函数加载任何 Bing 地图模块(如下所示)。这大大清理了代码,但似乎对内存使用没有太大影响。
- 正在同步加载地图。然而,这似乎破坏了与站点上的 Bing 地图有关的几乎所有内容。
- 收到消息后停止处理地图。这有助于密钥使用,但对内存使用没有帮助。
相关代码:
这是地图初始化函数(运行 由 HTML 中的 Bing 地图调用异步调用):
function initialize () {
const CENTER = new Microsoft.Maps.Location(44.96375272262944, -93.2353971897461);
// Assigns the zoom depending on whether the device is a mobile device or not
if (isMobile()) {
zoom = 12;
} else {
zoom = 13;
}
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById('map-canvas'), {
credentials: API_KEY,
minZoom: zoom,
center: CENTER,
disableStreetside: true,
disableStreetsideAutoCoverage: true,
enableClickableLogo: false,
showLocateMeButton: false,
showMapTypeSelector: false
});
bus1 = {
assignment: null,
destination: null,
distance: null,
eta: null,
location: null,
mph: null,
name: null,
pin: new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: 'img/bus1.png',
anchor: new Microsoft.Maps.Point(14, 44),
visible: false,
text: "",
title: ""
}),
polylineRender: null,
time: null,
timeout: null,
};
bus2 = {
assignment: null,
destination: null,
distance: null,
eta: null,
location: null,
mph: null,
name: null,
pin: new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: 'img/bus2.png',
anchor: new Microsoft.Maps.Point(14, 44),
visible: false,
text: "",
title: ""
}),
polylineRender: null,
time: null,
timeout: null,
};
bus3 = {
assignment: null,
destination: null,
distance: null,
eta: null,
location: null,
mph: null,
name: null,
pin: new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: 'img/bus3.png',
anchor: new Microsoft.Maps.Point(14, 44),
visible: false,
text: "",
title: ""
}),
polylineRender: null,
time: null,
timeout: null,
};
buses = [bus1, bus2, bus3];
// Add the traffic layer
Microsoft.Maps.loadModule('Microsoft.Maps.Traffic', function () {
trafficLayer = new Microsoft.Maps.Traffic.TrafficManager(map);
});
// Add the directions manager
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function () {
bus1.polylineRender = new Microsoft.Maps.Directions.DirectionsManager(map);
bus2.polylineRender = new Microsoft.Maps.Directions.DirectionsManager(map);
bus3.polylineRender = new Microsoft.Maps.Directions.DirectionsManager(map);
Microsoft.Maps.Events.addHandler(bus1.polylineRender, 'directionsError', function (e) {
console.log("Error: " + e.message + "\r\nResponse Code: " + e.responseCode);
});
Microsoft.Maps.Events.addHandler(bus1.polylineRender, 'directionsUpdated', directionsUpdated);
Microsoft.Maps.Events.addHandler(bus2.polylineRender, 'directionsError', function (e) {
console.log("Error: " + e.message + "\r\nResponse Code: " + e.responseCode);
});
Microsoft.Maps.Events.addHandler(bus2.polylineRender, 'directionsUpdated', directionsUpdated);
Microsoft.Maps.Events.addHandler(bus3.polylineRender, 'directionsError', function (e) {
console.log("Error: " + e.message + "\r\nResponse Code: " + e.responseCode);
});
Microsoft.Maps.Events.addHandler(bus3.polylineRender, 'directionsUpdated', directionsUpdated);
});
// Defines the polygons surrounding each campus
polygonArrSTP = [
new Microsoft.Maps.Location(44.94619673931851, -93.19240808486938),
new Microsoft.Maps.Location(44.941321471037966, -93.19249391555786),
new Microsoft.Maps.Location(44.94130628263941, -93.19764375686646),
new Microsoft.Maps.Location(44.93790398010943, -93.1975257396698),
new Microsoft.Maps.Location(44.937926764055824, -93.1924831867218),
new Microsoft.Maps.Location(44.94164802063501, -93.19241881370544),
new Microsoft.Maps.Location(44.94164802063501, -93.18739771842957),
new Microsoft.Maps.Location(44.94618914576464, -93.18735480308533),
new Microsoft.Maps.Location(44.94618914576464, -93.1924295425415),
];
polygonArrMPLS = [
new Microsoft.Maps.Location(44.97380025938377, -93.2795798778534),
new Microsoft.Maps.Location(44.97295018417148, -93.27883958816528),
new Microsoft.Maps.Location(44.97264658282772, -93.27782034873962),
new Microsoft.Maps.Location(44.973595331690625, -93.27698349952698),
new Microsoft.Maps.Location(44.9745744240603, -93.27614665031433),
new Microsoft.Maps.Location(44.97501463068608, -93.27712297439575),
new Microsoft.Maps.Location(44.9747205274961, -93.27738046646118),
new Microsoft.Maps.Location(44.974339139822895, -93.27832460403442),
new Microsoft.Maps.Location(44.97380025938377, -93.2795798778534)
];
// Adds the campus polygons to the map
polygonMPLS = new Microsoft.Maps.Polygon(polygonArrMPLS, {
fillColor: "rgba(255, 0, 0, 0.4)",
strokeColor: '#FF0000',
strokeThickness: 2
});
polygonSTP = new Microsoft.Maps.Polygon(polygonArrSTP, {
fillColor: "rgba(255, 0, 0, 0.4)",
strokeColor: '#FF0000',
strokeThickness: 2
});
// Assign the polygons to the Map
map.entities.push(polygonMPLS);
map.entities.push(polygonSTP);
// Set the toggle for advanced mode
advancedModeEnabled = false;
generateBusStats();
subscribeToPubnub();
console.log("Initialization complete.");
}
这是 运行 收到消息后的函数:
function redraw(payload) {
// If the user is does not have the page active, the payload is refused
if (!acceptingPayloads) {
return false;
}
let location = new Microsoft.Maps.Location(payload.message.lat, payload.message.lng);
let name = payload.message.name;
let dest = payload.message.dest;
let mph = payload.message.mph;
const STP = new Microsoft.Maps.Location(44.9416428, -93.1917952);
const MPLS = new Microsoft.Maps.Location(44.9747502, -93.2774464);
if (dest.toUpperCase() === "S") {
dest = {letter: "S", name: "St. Paul", coords: STP};
} else if (dest.toUpperCase() === "M") {
dest = {letter: "M", name: "Minneapolis", coords: MPLS};
} else {
dest = null;
}
console.log(name + ": " + location.latitude + ", " + location.longitude + " - " + dest.name + " - " + mph + " mph");
// Gets the bus object that the payload was sent from
currentBus = getCurrentBus(name);
// Removes the timeout for the current bus
if (currentBus.timeout !== null) {
clearTimeout(currentBus.timeout);
}
currentBus.location = location;
currentBus.destination = dest;
currentBus.mph = mph;
currentBus.time = Date.now();
currentBus.name = name;
// Restart the timeout for the current bus
beginTimeout();
// Calculate the distance between the current bus and its destination
calcDistToDest();
$("." + currentBus.assignment + "-item").css('display', 'block')
}
最后,这是我用来获取点之间距离的函数:
function calcDistToDest() {
// Clear all information from the Directions Manager
currentBus.polylineRender.clearAll();
// Set Route Mode to driving and the render options
currentBus.polylineRender.setRequestOptions({
routeMode: Microsoft.Maps.Directions.RouteMode.driving
});
currentBus.polylineRender.setRenderOptions({
autoUpdateMapView: false,
drivingPolylineOptions: {
visible: POLYLINE_VISIBILITY
},
waypointPushpinOptions: {
visible: false
},
firstWaypointPushpinOptions: {
anchor: currentBus.pin.getAnchor(),
icon: currentBus.pin.getIcon(),
title: currentBus.pin.getTitle(),
text: currentBus.pin.getText()
}
});
// Sets the waypoint of the bus's current position and destination
currentBus.polylineRender.addWaypoint( new Microsoft.Maps.Directions.Waypoint({
location: currentBus.location
}));
currentBus.polylineRender.addWaypoint( new Microsoft.Maps.Directions.Waypoint({
location: currentBus.destination.coords
}));
// Calculate the directions
currentBus.polylineRender.calculateDirections();
}
基本上我正在寻找的是一种找出导致此问题的原因的方法,如果问题很简单并且我只是遗漏了一些明显的问题,则可以找到该问题的实际解决方案,或者避免此问题的最佳做法首先。
注意:我很抱歉post编写了这么多代码。很难确定 post 的代码是什么,因为我真的不知道代码的哪一部分导致了这个问题。让我知道这是否需要修改或是否需要任何其他信息,我很乐意帮忙。我还在同一个文件中遗漏了很多看似不相关的 JS 代码,如果需要我很乐意添加它。
根据 rbrundritt 的建议,通过实施 Bing 地图的实验分支主要解决了内存泄漏问题。
以下是如何使用实验分支导入 Bing 地图的示例:
<script src='https://www.bing.com/api/maps/mapcontrol?branch=experimental&callback=[Insert callback function]' async defer></script>
我后来能够切换回发布分支,因为内存泄漏的修复已推送到该分支。有关 Bing Maps 地图控制分支的更多信息,请参见 here。
概述: 我一直在处理的这个项目从外部源接收消息并根据收到的信息更新 Bing 地图。但是,当我让页面 运行 长时间运行时,页面最终会耗尽所有内存并自行崩溃。
细节: 这个 memory issue 在我从 Google 地图切换到 Bing 地图后出现,我无法解决无论我尝试过什么。我进行了全面搜索,试图通过 Bing 地图最佳做法解决此问题,或者至少找到导致此问题的原因,但我一直无法找到真正解决问题的任何方法。
我有大量 detached DOMs 并尝试使用 Google Chrome 的控制台更仔细地分析它们,但没有成功。
尝试的修复:
- 将与添加处理程序有关的所有事情都移到地图初始化函数中(如下所示),但这似乎并没有太大改善。
- 正在从地图初始化函数加载任何 Bing 地图模块(如下所示)。这大大清理了代码,但似乎对内存使用没有太大影响。
- 正在同步加载地图。然而,这似乎破坏了与站点上的 Bing 地图有关的几乎所有内容。
- 收到消息后停止处理地图。这有助于密钥使用,但对内存使用没有帮助。
相关代码:
这是地图初始化函数(运行 由 HTML 中的 Bing 地图调用异步调用):
function initialize () {
const CENTER = new Microsoft.Maps.Location(44.96375272262944, -93.2353971897461);
// Assigns the zoom depending on whether the device is a mobile device or not
if (isMobile()) {
zoom = 12;
} else {
zoom = 13;
}
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById('map-canvas'), {
credentials: API_KEY,
minZoom: zoom,
center: CENTER,
disableStreetside: true,
disableStreetsideAutoCoverage: true,
enableClickableLogo: false,
showLocateMeButton: false,
showMapTypeSelector: false
});
bus1 = {
assignment: null,
destination: null,
distance: null,
eta: null,
location: null,
mph: null,
name: null,
pin: new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: 'img/bus1.png',
anchor: new Microsoft.Maps.Point(14, 44),
visible: false,
text: "",
title: ""
}),
polylineRender: null,
time: null,
timeout: null,
};
bus2 = {
assignment: null,
destination: null,
distance: null,
eta: null,
location: null,
mph: null,
name: null,
pin: new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: 'img/bus2.png',
anchor: new Microsoft.Maps.Point(14, 44),
visible: false,
text: "",
title: ""
}),
polylineRender: null,
time: null,
timeout: null,
};
bus3 = {
assignment: null,
destination: null,
distance: null,
eta: null,
location: null,
mph: null,
name: null,
pin: new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: 'img/bus3.png',
anchor: new Microsoft.Maps.Point(14, 44),
visible: false,
text: "",
title: ""
}),
polylineRender: null,
time: null,
timeout: null,
};
buses = [bus1, bus2, bus3];
// Add the traffic layer
Microsoft.Maps.loadModule('Microsoft.Maps.Traffic', function () {
trafficLayer = new Microsoft.Maps.Traffic.TrafficManager(map);
});
// Add the directions manager
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function () {
bus1.polylineRender = new Microsoft.Maps.Directions.DirectionsManager(map);
bus2.polylineRender = new Microsoft.Maps.Directions.DirectionsManager(map);
bus3.polylineRender = new Microsoft.Maps.Directions.DirectionsManager(map);
Microsoft.Maps.Events.addHandler(bus1.polylineRender, 'directionsError', function (e) {
console.log("Error: " + e.message + "\r\nResponse Code: " + e.responseCode);
});
Microsoft.Maps.Events.addHandler(bus1.polylineRender, 'directionsUpdated', directionsUpdated);
Microsoft.Maps.Events.addHandler(bus2.polylineRender, 'directionsError', function (e) {
console.log("Error: " + e.message + "\r\nResponse Code: " + e.responseCode);
});
Microsoft.Maps.Events.addHandler(bus2.polylineRender, 'directionsUpdated', directionsUpdated);
Microsoft.Maps.Events.addHandler(bus3.polylineRender, 'directionsError', function (e) {
console.log("Error: " + e.message + "\r\nResponse Code: " + e.responseCode);
});
Microsoft.Maps.Events.addHandler(bus3.polylineRender, 'directionsUpdated', directionsUpdated);
});
// Defines the polygons surrounding each campus
polygonArrSTP = [
new Microsoft.Maps.Location(44.94619673931851, -93.19240808486938),
new Microsoft.Maps.Location(44.941321471037966, -93.19249391555786),
new Microsoft.Maps.Location(44.94130628263941, -93.19764375686646),
new Microsoft.Maps.Location(44.93790398010943, -93.1975257396698),
new Microsoft.Maps.Location(44.937926764055824, -93.1924831867218),
new Microsoft.Maps.Location(44.94164802063501, -93.19241881370544),
new Microsoft.Maps.Location(44.94164802063501, -93.18739771842957),
new Microsoft.Maps.Location(44.94618914576464, -93.18735480308533),
new Microsoft.Maps.Location(44.94618914576464, -93.1924295425415),
];
polygonArrMPLS = [
new Microsoft.Maps.Location(44.97380025938377, -93.2795798778534),
new Microsoft.Maps.Location(44.97295018417148, -93.27883958816528),
new Microsoft.Maps.Location(44.97264658282772, -93.27782034873962),
new Microsoft.Maps.Location(44.973595331690625, -93.27698349952698),
new Microsoft.Maps.Location(44.9745744240603, -93.27614665031433),
new Microsoft.Maps.Location(44.97501463068608, -93.27712297439575),
new Microsoft.Maps.Location(44.9747205274961, -93.27738046646118),
new Microsoft.Maps.Location(44.974339139822895, -93.27832460403442),
new Microsoft.Maps.Location(44.97380025938377, -93.2795798778534)
];
// Adds the campus polygons to the map
polygonMPLS = new Microsoft.Maps.Polygon(polygonArrMPLS, {
fillColor: "rgba(255, 0, 0, 0.4)",
strokeColor: '#FF0000',
strokeThickness: 2
});
polygonSTP = new Microsoft.Maps.Polygon(polygonArrSTP, {
fillColor: "rgba(255, 0, 0, 0.4)",
strokeColor: '#FF0000',
strokeThickness: 2
});
// Assign the polygons to the Map
map.entities.push(polygonMPLS);
map.entities.push(polygonSTP);
// Set the toggle for advanced mode
advancedModeEnabled = false;
generateBusStats();
subscribeToPubnub();
console.log("Initialization complete.");
}
这是 运行 收到消息后的函数:
function redraw(payload) {
// If the user is does not have the page active, the payload is refused
if (!acceptingPayloads) {
return false;
}
let location = new Microsoft.Maps.Location(payload.message.lat, payload.message.lng);
let name = payload.message.name;
let dest = payload.message.dest;
let mph = payload.message.mph;
const STP = new Microsoft.Maps.Location(44.9416428, -93.1917952);
const MPLS = new Microsoft.Maps.Location(44.9747502, -93.2774464);
if (dest.toUpperCase() === "S") {
dest = {letter: "S", name: "St. Paul", coords: STP};
} else if (dest.toUpperCase() === "M") {
dest = {letter: "M", name: "Minneapolis", coords: MPLS};
} else {
dest = null;
}
console.log(name + ": " + location.latitude + ", " + location.longitude + " - " + dest.name + " - " + mph + " mph");
// Gets the bus object that the payload was sent from
currentBus = getCurrentBus(name);
// Removes the timeout for the current bus
if (currentBus.timeout !== null) {
clearTimeout(currentBus.timeout);
}
currentBus.location = location;
currentBus.destination = dest;
currentBus.mph = mph;
currentBus.time = Date.now();
currentBus.name = name;
// Restart the timeout for the current bus
beginTimeout();
// Calculate the distance between the current bus and its destination
calcDistToDest();
$("." + currentBus.assignment + "-item").css('display', 'block')
}
最后,这是我用来获取点之间距离的函数:
function calcDistToDest() {
// Clear all information from the Directions Manager
currentBus.polylineRender.clearAll();
// Set Route Mode to driving and the render options
currentBus.polylineRender.setRequestOptions({
routeMode: Microsoft.Maps.Directions.RouteMode.driving
});
currentBus.polylineRender.setRenderOptions({
autoUpdateMapView: false,
drivingPolylineOptions: {
visible: POLYLINE_VISIBILITY
},
waypointPushpinOptions: {
visible: false
},
firstWaypointPushpinOptions: {
anchor: currentBus.pin.getAnchor(),
icon: currentBus.pin.getIcon(),
title: currentBus.pin.getTitle(),
text: currentBus.pin.getText()
}
});
// Sets the waypoint of the bus's current position and destination
currentBus.polylineRender.addWaypoint( new Microsoft.Maps.Directions.Waypoint({
location: currentBus.location
}));
currentBus.polylineRender.addWaypoint( new Microsoft.Maps.Directions.Waypoint({
location: currentBus.destination.coords
}));
// Calculate the directions
currentBus.polylineRender.calculateDirections();
}
基本上我正在寻找的是一种找出导致此问题的原因的方法,如果问题很简单并且我只是遗漏了一些明显的问题,则可以找到该问题的实际解决方案,或者避免此问题的最佳做法首先。
注意:我很抱歉post编写了这么多代码。很难确定 post 的代码是什么,因为我真的不知道代码的哪一部分导致了这个问题。让我知道这是否需要修改或是否需要任何其他信息,我很乐意帮忙。我还在同一个文件中遗漏了很多看似不相关的 JS 代码,如果需要我很乐意添加它。
根据 rbrundritt 的建议,通过实施 Bing 地图的实验分支主要解决了内存泄漏问题。
以下是如何使用实验分支导入 Bing 地图的示例:
<script src='https://www.bing.com/api/maps/mapcontrol?branch=experimental&callback=[Insert callback function]' async defer></script>
我后来能够切换回发布分支,因为内存泄漏的修复已推送到该分支。有关 Bing Maps 地图控制分支的更多信息,请参见 here。