1

I must use javascript for a project but I don't know anything about javascript. In the js file I use jVectorMap to display a world map which is "updated" every 5 seconds. When I open the web page using this javascript file in my web client and wait for some hours my computer runs out of RAM. I use chrome dev console and profile tool to identify the part of the code producing this issue. When I remove this part there is no memory usage issue.

The part of the code is :

function ui_geo_map(countriesCount) {
    $('#geo-world-map').empty();
    $('#geo-world-map').vectorMap({
        map: 'world_mill_en',
        series: {
            regions: [{
                values: countriesCount,
                scale: ['#2ecc71', '#c0392b'],
                normalizeFunction: 'polynomial',
                legend: {vertical: true}
            }]
        },
        onRegionTipShow: function(e, el, code){
            el.html(el.html() + ' (' + countriesCount[code] + ' - servers)');
        }
    });
};

function ui_geo() {
    console.debug('Redrawing the geo map');
    $('.pywos-geo').remove();
    $.getJSON('/get/geo/all', function(data){
        $.each(data, function(key, val){
            countriesCount[val.country_code] = val.count;
        });
        ui_geo_map(countriesCount);
    });
};

I know the empty followed by vectorMap is certainly not the right way to do it but if I remove $('#geo-world-map').empty(); the map is not replaced, instead it is displayed under the previous one which is not what I want.

Can someone help me find the right way to do it without any memory leaks ?

justcurious
  • 839
  • 3
  • 12
  • 29
selfm
  • 101
  • 1
  • 9
  • you might want to use [`remove()` instead of `empty()`](http://stackoverflow.com/questions/3090662/jquery-empty-vs-remove) so the nodes inside `$('#geo-world-map')` will be removed instead of just emptied. But I have little hope that this will solve your issue since both functions do not leak memory. Make sure you have the latest jquerylibrary tho. You may go ahead and remove some more code until you find the leak – InsOp Oct 08 '15 at 13:35
  • @InsOp : thanks for your answer. If I remove any call to ui_geo() or if I do not allow it to update every 5 seconds, there is no memory usage issue. This is why I think the issue comes from this function. – selfm Oct 08 '15 at 13:58
  • is this the case if you comment out `ui_geo_map(countriesCount);` in your `ui_geo()`-function, too? – InsOp Oct 08 '15 at 14:06
  • If I only comment out the call to ui_geo_map() there is no memory usage issue. – selfm Oct 08 '15 at 14:35
  • Okay try to call `delete $('#geo-world-map').vectorMap;` right after `$('#geo-world-map').empty();` – InsOp Oct 08 '15 at 14:39
  • Okay this cant be the problem. it could be that `onRegionTipShow` is the troublemaker here - try commenting that out – InsOp Oct 08 '15 at 14:45
  • I add the delete statement but unfortunately it doesn't help. The memory usage keep increase. – selfm Oct 08 '15 at 14:46
  • try my other suggestion, then – InsOp Oct 08 '15 at 14:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/91761/discussion-between-insop-and-selfm). – InsOp Oct 08 '15 at 14:53

1 Answers1

1

First of all there is a method remove which you should call on jVectorMap instance which gracefully removes all the DOM elements and linked JS objects:

var map = new jvm.Map({
    container: $('#geo-world-map'),
    map: 'world_mill_en',
    series: {
        regions: [{
            values: countriesCount,
            scale: ['#2ecc71', '#c0392b'],
            normalizeFunction: 'polynomial',
            legend: {vertical: true}
        }]
    },
    onRegionTipShow: function(e, el, code){
        el.html(el.html() + ' (' + countriesCount[code] + ' - servers)');
    }
});

Also there is not need to recreate the whole map every time you need to update values (this is a great waste of resources), you can just update data:

$.getJSON('/get/geo/all', function(data){
    $.each(data, function(key, val){
        countriesCount[val.country_code] = val.count;
    });
    map.series.regions[0].setValues(countriesCount);
});
bjornd
  • 22,397
  • 4
  • 57
  • 73
  • Thanks a lot for your answer. I understand the point here. However I'm not a js expert at all and I got an NS_ERROR_FAILURE when I use this code. – selfm Oct 09 '15 at 13:55
  • countriesCount is not defined at chen map is declared and the coutries only color is black, there is no legend and nothing seems to be updated. – selfm Oct 09 '15 at 14:56