Dispose an image object

2020-06-12 04:32发布

When creating a new Image element in javascript, Google Chrome's memory tool (Developer tools > Timeline > Memory) considers it as a new DOM element, naturally.

In my case, I'm ending up with 1500+ DOM elements, and I wish to get rid of them. I have tried to save all objects in an array and delete all of them in a loop when I'm ready creating all objects, resulting in the following error:

Uncaught TypeError: Cannot call method 'removeChild' of null

That indicates the Image objects doesn't appear in the actual DOM.

var images = [];
var i, image;

for( i = 0; i < urls.length; i++ ) {
    image = new Image();
    image.src = urls[i];
}

// other stuff happens

for( i = 0; i < images.length; i++ ) {
    // apparently this doesn't work because I'm not adding the image to my DOM
    // images[i].parentNode.removeChild( images[i] );

    // delete images
}

Is there a way to remove/delete/unset/dispose the Image objects?

5条回答
够拽才男人
2楼-- · 2020-06-12 05:17

If you are not adding them to the DOM (like using appendChild to a parent), then removeChild is useless. The Image objects are only in the memory.

And to dispose items in the memory, you only need to remove references to these objects (like set the referencing variable to null), and garbage collection will do the rest. If you can't null them all, they won't be GC'ed.

查看更多
我只想做你的唯一
3楼-- · 2020-06-12 05:21

AFAIK, assigning null should clean it up: images[i] = null

查看更多
\"骚年 ilove
4楼-- · 2020-06-12 05:22

I think only way is to do this:

for( i = 0; i < images.length; i++ ) 
  images[i] = null;
}

// or just 
images = null;
查看更多
祖国的老花朵
5楼-- · 2020-06-12 05:24

Setting images = null would remove your reference in code to the object. However, to implement its load event, Chrome has to have its own internal reference to the object.

That is, you could have code like this:

for( i = 0; i < urls.length; i++ ) { 
    image = new Image(); 
    image.src = urls[i]; 
    image.onload = function(){alert('Test');};
    image = null;
} 

This way you would still get a lot of "Test" alerts, even though you do not have a reference to these objects.

Hence, my guess is that it is a bug in Chrome, not in your code.

Update: looking through the Chromium source sort of proves that (I mean the comment on lines 67-71 of this file, especially the FIXME note http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp ):

// Make sure the document is added to the DOM Node map. Otherwise, the HTMLImageElement instance
// may end up being the only node in the map and get garbage-ccollected prematurely.
// FIXME: The correct way to do this would be to make HTMLImageElement derive from
// ActiveDOMObject and use its interface to keep its wrapper alive. Then we would
// remove this code and the special case in isObservableThroughDOM.
查看更多
欢心
6楼-- · 2020-06-12 05:25

To get rid of the bug described by "naivists" of chrome and specilly IE and EDGE. You can change the image source to empty so it take zero memory.

image.src = '';
image = null;
查看更多
登录 后发表回答