#17 Major Memory Leak in Vehicle Map JavaScript Code

closed-fixed
nobody
None
5
2012-04-17
2011-08-31
YanXu
No

Client Tested on: Windows XP, IE8 & Chrome
Server runs on: OpenSUSE linux
Map Provider: OpenLayers / OSM

After leaving the browser window with the vehicle map view open and having the auto-update enabled, I noticed a serious JavaScript memory leak. This can also be triggered by manually hitting the button to update the map markers.

After every update, the memory increases by 30-35MB on Internet Explorer 8. I've tested it on Chrome and get the same result with a slight different absolute value of increase. The screenshot shows the memory consumption of the IE8 have on tab open. Every step on the memory graph is caused after clicking update. This has no end. It only stops when refreshing the page.

I've already tried to find the leak using JSLint, IEJSLeaksDetector and Chrome Heap Snapshot Comparison but with no result. The latter clearly shows the huge memory increase but there are hundreds of thousands of unnamed objects and I just don't know where to start.

I think someone who wrote most of the code probably knows better where to look first. Usually memory leaks emerge when using circular references starting from the DOM to one or more arrays/objects back to the DOM. But probably ist just that the map object or the pushpin objects are not properly deleted by setting the reference explicitly to null. But this is all just a guess.

Discussion

  • YanXu
    YanXu
    2011-08-31

    Screenshot of the memory leak in process explorer

     
  • YanXu
    YanXu
    2011-09-28

    • status: open --> open-fixed
     
  • YanXu
    YanXu
    2011-09-28

    Hey,

    this issue was a major show stopper for us because we needed auto-update which causes the browser to crash when it runs out-of-memory after some time because of the memory leak.

    So I did some further profiling with Chrome, compared memory snapshots and found out that for each Marker, the OpenLayers objects Size, Pixel, LonLat, Events, Bounds, Icon, Marker and Popup as well as the GTS specific objects JSMapPushPin, MapEventRecord, JSDetailPoint, JSMapPoint and JSMapDataSet were retained in Memory.

    Using the snapshot comparison, I could foind the object still held a reference to these objects which were mainly the event handlers "mouseover" etc.

    Actually, in "JSMap.prototype._clearMarkerLayer" you were trying to remove all object by calling "this.markerLayer.clearMarkers()". But this did only remove the objects from the marker layer but not from the event handling routines. This is done by calling the ".destroy()" fuction that almost every OpenLayers class has.

    The main fix was remembering the popup objects in a new array and by adding this to the "_clearMarkerLayer" function:

    var markers = this.markerLayer.markers;
    try {
    if(markers !== null) {
    for (i = 0; i < markers.length; i++) {
    /* This is necessary to remove the event listeners, too */
    markers[i].destroy();
    }
    markers = null;
    }
    } catch (e) {}
    try {
    if(this.popups !== null) {
    for (i = 0; i < this.popups.length; i++) {
    this.popups[i].destroy();
    }
    this.popups = [];
    }
    } catch (e) {}

    I will upload my fixed Version of "OpenLayers.js"

     
  • YanXu
    YanXu
    2011-09-28

    This is the fixed version of the GTS specific wrapper for OpenLayers in /war/track/js

     
    Attachments
  • Martin Flynn
    Martin Flynn
    2011-10-03

    • status: open-fixed --> pending-fixed
     
  • Martin Flynn
    Martin Flynn
    2011-10-03

    Thanks, fixed will be applied int he next release.

     
  • Martin Flynn
    Martin Flynn
    2011-10-10

    v2.3.8 released which should include a fix for this issue.

     
  • Martin Flynn
    Martin Flynn
    2012-04-17

    • status: pending-fixed --> closed-fixed
     
  • Martin Flynn
    Martin Flynn
    2012-04-17

    Should be fixed in the latest available release.