How to destroy a JavaScript object?
Asked Answered
V

5

91

Recently, I came across one of my application which consumes too much memory and increasing by 10 MB/sec.

So, I like to know how to destroy JavaScript object and variables so memory consumption stays down and my FF can't get destroyed.

I am calling two of my scripts every 8 seconds without reloading the page.

function refresh() {
    $('#table_info').remove();
    $('#table').hide();
    if (refreshTimer) {
        clearTimeout(refreshTimer);
        refreshTimer = null ;
    }
    document.getElementById('refresh_topology').disabled=true; 
    $('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
    $("#topo").hide();
    $('#root').remove();
    show_topology();
}

How can I see which variable cause Memory overhead, what's the method to stop the execution of that process?

Vantage answered 20/4, 2012 at 12:25 Comment(3)
Have you considered isolating portions of your codes using closures ?Capo
Have you tried anything? Like using obj = null?Zeebrugge
A) What does show_topology do? --- B) Are you ever clearing out the things you add to #td_123? --- C) Is there a live version of this somewhere?Ephemeral
V
108

You could put all of your code under one namespace like this:

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

Using the delete keyword will delete the reference to the property, but on the low level the JavaScript garbage collector (GC) will get more information about which objects to be reclaimed.

You could also use Chrome Developer Tools to get a memory profile of your app, and which objects in your app are needing to be scaled down.

Vital answered 20/4, 2012 at 12:39 Comment(3)
Press F12 to get developer tools. Go to the Profile tab and Click on Start to start the profile. You can do the profiling on JS CPU, CSS Selector and you can take the Heap snapshot.Derina
or in latest chrome type the word performance in the js consoleCaithness
Perhaps it is obvious, but you can name your namespace something like "g" and save lots of typing. Use g.curItem=... instead of var curItem=... and save typing as well as allowing for g=undefined to clear out all global memory allocation.Pressure
M
33

You can't delete objects, they are removed when there are no more references to them. You can delete references with delete.

However, if you have created circular references in your objects you may have to de-couple some things.

Mischievous answered 20/4, 2012 at 12:30 Comment(3)
Could you add an example of a circular reference which wouldn't be caught by the garbage collector? Asking for a friend! ;)Epperson
@emilhem you can reference the garbage collector and it will delete itself and the internet - the implosion possibly creating a blackhole at CERN. Have you thought about that example?Tillio
@EmilHemdal V8 uses two mark-and-compact garbage collectors, which means that even if you make a circular reference, it will eventually be collected if it can't be reached from a global (or old object, but that only lets it survive two collections)Racon
U
30

While the existing answers have given solutions to solve the issue and the second half of the question, they do not provide an answer to the self discovery aspect of the first half of the question that is in bold:

"How can I see which variable causes memory overhead...?"

It may not have been as robust 3 years ago, but the Chrome Developer Tools "Profiles" section is now quite powerful and feature rich. The Chrome team has an insightful article on using it and thus also how garbage collection (GC) works in javascript, which is at the core of this question.

Since delete is basically the root of the currently accepted answer by Yochai Akoka, it's important to remember what delete does. It's irrelevant if not combined with the concepts of how GC works in the next two answers: if there's an existing reference to an object it's not cleaned up. The answers are more correct, but probably not as appreciated because they require more thought than just writing 'delete'. Yes, one possible solution may be to use delete, but it won't matter if there's another reference to the memory leak.

Another answer appropriately mentions circular references and the Chrome team documentation can provide much more clarity as well as the tools to verify the cause.

Since delete was mentioned here, it also may be useful to provide the resource Understanding Delete. Although it does not get into any of the actual solution which is really related to javascript's garbage collector.

Unimproved answered 16/10, 2015 at 17:47 Comment(0)
P
9

Structure your code so that all your temporary objects are located inside closures instead of global namespace / global object properties and go out of scope when you've done with them. GC will take care of the rest.

Pierce answered 20/4, 2012 at 12:29 Comment(0)
V
1

I was facing a problem like this, and had the idea of simply changing the innerHTML of the problematic object's children.

adiv.innerHTML = "<div...> the original html that js uses </div>";

Seems dirty, but it saved my life, as it works!

Vireo answered 10/6, 2013 at 20:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.