using jQuery remove() causes memory leak

2019-04-16 11:18发布

问题:

I have a div in which I frequently create child divs and later remove them. The insert function looks like this.

var insert = function(container, content) {
    content = $(content);
    container.append(content);
    return content;
};

var newContent = insert($('#container'), '<div>new content</div>');

// later
newContent.remove();

container is a jQuery object. content is a string like <div>new content</div>. Later, that new content is removed.

The div is properly removed from the dom, but using chrome's profiling feature, I can see memory grow and grow. The profile shows a list of strings, thousands of which are my deleted content. Tracking it down, I see that jquery has a property called fragments.

$.fragments is a map where the key strings are html fragments (literally <div>new content</div> is the key string) and the values are DocumentFragment objects.

The DocumentFragment objects contain a property 'native' which contains a value of type 'Detached DOM tree'. And there is my detached object.

It seems like the problem is that jQuery is not flushing this $.fragments collection. I'm using jQuery 1.7.1.

One possible reason I could see for this is that the keys of the map are html that was inserted, but by the time I get around to deleting the fragment, I've changed the newContent div's attributes.

One possible solution is to keep a pool of unused new content divs and re-use them. I don't really want to do that, but it might be reasonable.

回答1:

It does look like jQuery is using $.fragments to speed up $("<...>") then.

I suppose using $("<div>").html(...) would not use the cache, but it's obviously semantically different.

You could just try occasionally flushing $.fragments yourself and see what happens. I have the gut feeling everything would go just as expected with no ill effects.

I don't think jQuery really has a way to track the fragment cache usage itself, and an LRU cache or somesuch would probably be slower, not to mention more trouble implementing.