Chrome Memory/Garbage Collection Issue

2019-04-14 01:44发布

问题:

I am having memory/garbage collection issues with Chrome

I am working on a photo uploading site which allows my client to drag and drop photos to upload using HTML5 and file API, so this wont work in IE. it only works in Chrome and FF. I haven't tested in Safari, Opera yet.

I am not using any JS frameworks and my example is less than 80 lines of code, so it's really easy to follow.

Here is my example: http://seesquaredphoto.com/testPreview.html

If you drag and drop a handful of JPG photos (4-5MB each) into the box you will see the previews load and in windows task manager, you can see the memory usage climb for that window. If you click the "Clear Images" button, the images are deleted.

If you do this in FF, after a few seconds, the memory returns to back what it was before you previewed the images. However in chrome, the memory does not drop.

Any ideas? Am i doing something wrong or is this a chrome bug?

Thanks. Here is the code if you dont want to view source the link above:

Javascript:

var upload = {        
    uploadFiles : function(event) {
        var files = event.dataTransfer.files;
        event.stopPropagation();
        event.preventDefault();

        var imageType = /image.*/;
        for (var x = 0; x < files.length; x++) {
            var file = files.item(x);
             if (!file.type.match(imageType) || file.fileName.toUpperCase().indexOf(".JPG")!=file.fileName.length-4) {  
               continue;  
             }      

            var s = document.createElement("span"); 
            s.className = "imgS";   
            var img = document.createElement("img");  
            img.className = "preview";  
            img.src = "";  

            s.appendChild(img);
            document.getElementById("DDCont").appendChild(s);
            loadPreview(img,file);
        }
    }
}; 
function loadPreview(img,file){
    var reader = new FileReader();  
    reader.onload = function(e) {
        img.src = e.target.result;
    }
    reader.readAsDataURL(file)
}
function init(){
    var container = document.getElementById('DDCont');
    container.addEventListener("dragenter", function(event) {
            event.stopPropagation();
            event.preventDefault();
        }, 
        false
    );
    container.addEventListener("dragover", function(event) {
            event.stopPropagation(); 
            event.preventDefault();
        },  
        false
    );
    container.addEventListener("dragleave", function(event) {
            event.stopPropagation(); 
            event.preventDefault();
        },  
        false
    );
    container.addEventListener("drop", upload.uploadFiles, false);
}   
function clearImages(){
    cont = document.getElementById("DDCont");
    while(cont.childNodes.length>0) {
         cont.removeChild(cont.childNodes[0]); 
    }
}

HTML:

<div id="DDCont" style="width:800px; height:600px; border:3px solid #333333; overflow:auto;"></div>
<input type="button" value="Clear Images" onclick="clearImages()"/>

回答1:

Yeah this is a big problem for me as well,
It seems that modern browsers dont free up resources, especially with Images. I think this should be a focus considering the massive amounts of Ajax pages, keeping state, and allowing the user to NOT refresh the page.

Luckily, with HTML5 video, you can achieve this by first changing the src

video.src=" ";
video.load();

If you do this before removing video elements, the memory is cleared.

Unfortunately I have no found a way to do this with Images, If it is found I would love to know.



回答2:

It seems your right, I believe it happens to any DOM removal, the memory isn't freed in Chrome. Same thing happens with Canvas:

http://code.google.com/p/chromium/issues/detail?id=40178

Perhaps you can submit a bug report (http://crbug.com/new), and after you do that, I will cc the appropriate team for more triaging.

Thanks!



回答3:

Apparently this have being fixed in recent versions of chromium (at least the video memory leak).

The fix can be found in chrome 49 and I believe this was the exact commit that fixed it: https://chromium.googlesource.com/chromium/src/+/d13710832e9d0e6302cf8388cda94a7a780d8664%5E%21/#F0

This means that the source hack is no longer needed.