2015-11-12 2 views
3

Я разрабатываю веб-приложение, которое каждый может редактировать изображение в Интернете напрямую.Утечка памяти CreateObjectURL в Chrome

При разработке сайта у меня возникла большая проблема с открытием локальных системных файлов.

Как правило, мы можем сделать это двумя способами, как это уже известно, как показано ниже.

Во-первых, для использования FileReader.

// render the image in our view 
function renderImage(file) { 

    // generate a new FileReader object 
    var reader = new FileReader(); 

    // inject an image with the src url 
    reader.onload = function(event) { 
    the_url = event.target.result 
    $('#some_container_div').html("<img src='" + the_url + "' />") 
    } 

    // when the file is read it triggers the onload event above. 
    reader.readAsDataURL(file); 
} 

// handle input changes 
$("#the-file-input").change(function() { 
    console.log(this.files) 

    // grab the first image in the FileList object and pass it to the function 
    renderImage(this.files[0]) 
}); 

second, использовать createObjectURL и revokeObjectURL.

window.URL = window.URL || window.webkitURL; 

var fileSelect = document.getElementById("fileSelect"), 
    fileElem = document.getElementById("fileElem"), 
    fileList = document.getElementById("fileList"); 

fileSelect.addEventListener("click", function (e) { 
    if (fileElem) { 
    fileElem.click(); 
    } 
    e.preventDefault(); // prevent navigation to "#" 
}, false); 

function handleFiles(files) { 
    if (!files.length) { 
    fileList.innerHTML = "<p>No files selected!</p>"; 
    } else { 
    fileList.innerHTML = ""; 
    var list = document.createElement("ul"); 
    fileList.appendChild(list); 
    for (var i = 0; i < files.length; i++) { 
     var li = document.createElement("li"); 
     list.appendChild(li); 

     var img = document.createElement("img"); 
     img.src = window.URL.createObjectURL(files[i]); 
     img.height = 60; 
     img.onload = function() { 
     window.URL.revokeObjectURL(this.src); 
     } 
     li.appendChild(img); 
     var info = document.createElement("span"); 
     info.innerHTML = files[i].name + ": " + files[i].size + " bytes"; 
     li.appendChild(info); 
    } 
    } 
} 

В моем случае оба они плохо работают в браузере Chrome. (IE в порядке) Я мог бы открыть локальные файлы, используя их оба. Но также, они всегда делали утечку памяти, хотя я точно назвал revokeObjectURL, когда использовал второй способ.

Я уже проверил, что капли освобождаются от chrome://blob-internals/. Весь blob был выпущен хорошо. Но Chrome все еще сохранил физическую память, и память не была выпущена навсегда, если я не обновляю страницу. В конце концов, Chrome был разбит при использовании памяти до 1,5 ГБ.

FileReader показал мне тот же результат, хотя я выпустил ссылки. Кроме того, этот способ показал ужасную производительность ввода-вывода.

http://ecobyte.com/tmp/chromecrash-1a.html (по logidelic)

Вот тестовая страница. Вы можете проверить эту проблему, просто отбросьте файлы на зеленый DOM. На странице тестирования используется метод createObjectURL/revokeObjectURL.

Когда вы проводите это тестирование, вы можете увидеть потребление физической памяти от диспетчера задач (Shift + ESC) или вашего собственного диспетчера задач ОС.

Я что-то пропустил или это ошибка, как уже известно?

Пожалуйста, помогите мне! Если вы знаете другой способ решить эту проблему, скажите мне.

ответ

0

У меня такая же проблема с методом createObjectURL. В конце концов, я считаю, что память может быть освобожден путем добавления кода в функции OnLoad:

this.src = ''; 

Однако изображение исчезнет с веб-страницы, как вы можете ожидать. Кроме того, я также замечаю, что иногда хром (50.0.2661.102) или хром канарейка (52.0.2740.0) не выпускает память даже с this.src = ''. Как только это произойдет, вам нужно перезапустить хром. Просто обновить страницу не работает.

Я тоже попробовал метод readAsDataURL. Память может быть выпущена хорошо (даже когда хром не освобождает память для createObjectURL с this.src = ''.) Однако недостатком является то, что скорость довольно медленная (примерно в 10 раз больше по сравнению с createObjectURL).