必应地图 V8 JS API 内存泄漏问题

3

概述: 我一直在处理一个项目,该项目接收来自外部源的消息,并根据接收到的信息更新Bing地图。但是,当我让页面运行很长时间时,页面最终会耗尽所有内存并崩溃。

具体问题: 当我从Google Maps切换到Bing Maps后,出现了内存问题,无论我尝试什么都无法解决。我已经搜索了所有相关资料,试图通过Bing Maps最佳实践来解决此问题,或者至少找到导致此问题的原因,但是我无法找到任何真正解决问题的方法。

我有大量的分离的DOM,并尝试使用Google Chrome的控制台更仔细地分析它们,但没有成功。

尝试修复:

  • 将添加处理程序的所有内容移动到地图初始化函数中(如下所示),但似乎没有太多改进。
  • 从地图初始化函数中加载任何Bing Maps模块(如下所示)。这样可以清理代码,但对内存使用似乎没有太大影响。
  • 同步加载地图。但是,这似乎破坏了与Bing Maps相关的所有内容。
  • 在接收到消息时停止处理地图。这有助于键使用,但对内存使用没有帮助。

相关代码:


这是地图初始化函数(由HTML中的Bing Maps调用异步运行):

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();
}

我需要找到导致这个问题的原因,如果问题很简单,只是我漏掉了一些明显的东西,那么我需要一个实际的解决方案,或者最佳实践来避免这个问题。

注意: 对于发布如此多的代码,我深感抱歉。由于我不知道哪一部分代码导致了这个问题,所以很难确定要发布哪些代码。如果需要修改或需要其他信息,请告诉我,我会尽力配合。此外,我还省略了同一文件中许多看似无关紧要的JS代码,如果需要,我可以添加它们。


你使用的是Bing Maps V8的哪个分支?冻结的分支已经一年多没有更新了,有很多已知的内存泄漏问题,在主要发布分支中已经修复了其中的许多问题。在实验分支中还有更多的修复。你使用的是哪个浏览器?我认为你报告的问题是IE已知的问题。 - rbrundritt
所以我一直在使用发布分支。这个问题似乎在Chrome、Firefox、IE和Edge上以相同的频率发生。 - Chase Ingebritson
1
你可以尝试使用实验分支来查看问题是否仍然存在。如果问题已经解决,它很可能会在主要发布分支中出现,如果及时完成发布,则可能会在下周发布,否则将在九月底左右发布。 - rbrundritt
1个回答

0

通过 rbrundritt 建议的实验分支的实施,主要解决了内存泄漏问题。

下面是使用实验分支导入必应地图的示例:

<script src='https://www.bing.com/api/maps/mapcontrol?branch=experimental&callback=[Insert callback function]' async defer></script>

后来,由于内存泄漏的修复已经推送到发布分支,我能够切换回发布分支。有关必应地图控件分支的更多信息,请单击此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接