Систематическое обновление SRC IMG.Утечка памяти - PullRequest
5 голосов
/ 10 сентября 2010

Систематическое обновление SRC IMG. Утечка памяти.

В настоящее время я обновляю изображение каждые x сек. Несколько способов, которыми я думал об этом, были следующими:

Take One:

var url ="...";
$('#ImageID').attr('src', url);

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

дубль два:

Итак, он создает элементы DOM, поэтому я попытался сделать следующее.

<div id="ImageHolder">

</div>

var image - "..."; //Obv actual image in working.

$('#ImageHolder').empty();
$('#ImageHolder').html(image);

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

Редактировать 1:

Мой код:

<form name="selected">
<input type="hidden" name="map" />
</form>

<img id="MyMaps" src="http://localhost/web/blank.png" alt="" />


<script type="text/javascript">
var locate = window.location;
var uri = document.selected.map.value;

var MyHost = window.location.hostname;
    function delineate2(name) {
        totheleft= uri.indexOf("maps/") + 5;
        totheright= uri.lastIndexOf("&");
        return (uri.substring(totheleft, totheright));
    }

    function loadImage() {
        var CurrentMap = delineate2(name);
        var url = 'http://' + MyHost+ '/map/' + CurrentMap+ '/image?' + new Date().getTime();

        $('#MyMaps').attr('src', url);

        setTimeout(loadImage, 10000);
    }
</script>

Кто-нибудь сделал что-то подобное и нашел рабочее решение, или как я могу предотвратить утечку памяти / мерцание при обновлении изображения?

Ответы [ 4 ]

2 голосов
/ 07 сентября 2016

Я использовал разные методы для решения этой проблемы, ни один из них не работает. Кажется, что утечка памяти происходит, когда img.src = base64string, и эта память никогда не может быть освобождена. Вот мое решение.

fs.writeFile('img0.jpg', img_data, function (err) {
    // console.log("save img!" );
});
document.getElementById("my-img").src =  'img0.jpg?'+img_step;
img_step+=1;

Приложение My Electron обновляется через каждые 50 мс, и память не протекает. Забудьте об использовании диска. Управление памятью в Chrome меня бесит.

2 голосов
/ 21 октября 2013

Я считаю, что ваш "взять один" должен работать. Не должно быть утечки памяти. Вы перезаписываете тег src каждый раз - если у вас нет других ссылок на старые изображения, они должны получить мусор. Я вижу эту проблему в FF и Chrome. Chrome говорит мне, что использование памяти JS является постоянным, память должна быть потеряна где-то еще. Я открыл ошибку Chrome: https://code.google.com/p/chromium/issues/detail?id=309543 Если вы хотите добавить свой вес и, возможно, пометить ошибку:)

2 голосов
/ 04 декабря 2015

вопрос 5 лет, но он все еще для меня "горячий", я хочу поделиться той же проблемой, с которой я только что столкнулся.

Подход "Take One", возможно, является самым первым подходом, который каждый программист использовал для изменения источника изображения, но до сих пор (через 5 лет после публикации этого вопроса) проблема все еще возникала, часто меняйте <img> 'src' и вы можете увидеть в диспетчере задач Windows, что ваш браузер стал жадным. «Взять два» создают мерцание, и это редко приемлемо. К счастью, html5 поставляется с <canvas>, поэтому я пытаюсь использовать <canvas> для решения этой проблемы.

var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
img = new Image();
img.onload = function () {
    ctx.drawImage(img, 0, 0);
    img.src = "";
}
img.src = "data:image/png;base64," + stringSource;

Обнаружена новая проблема, <canvas> отличная от <img>, она не будет автоматически изменять размеры и «соответствовать». Мы должны вручную изменить размер изображения, чтобы он соответствовал холсту и сохранял соотношение. Ниже приведен мой код для решения проблемы

var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
img = new Image();
img.onload = function () {
    var imageWidth = canvas.width;
    var imageHeight = canvas.height;
    var xPosition = 0;
    var yPosition = 0;
    var proportion = 1;
    var padding = 2;
    if ((img.width / canvas.width) > (img.height / canvas.height)) {
        proportion = img.width / canvas.width;
    }
    else {
        proportion = img.height / canvas.height;
    }
        imageWidth = img.width / proportion;
        imageHeight = img.height / proportion;
        xPosition = (canvas.width - imageWidth) / 2;
        yPosition = (canvas.height - imageHeight) / 2;
        ctx.drawImage(img, 0, 0, img.width, img.height, xPosition+padding, yPosition+padding, imageWidth-2*padding, imageHeight-2*padding);
            img.src = "";
    }
    img.src = "data:image/png;base64," + stringSource;

Надеюсь, это поможет любому, кто столкнется с той же проблемой.

2 голосов
/ 10 сентября 2010

Я никогда не думал о том, чтобы делать это как твой кулачный метод ... интересно. Я могу себе представить, что это вызывает утечку памяти, потому что каждое изображение хранится в памяти, потому что на самом деле ничего не удаляется. Это всего лишь предположение.

Я бы рекомендовал придерживаться второго метода, но изменить его, чтобы решить проблему мерцания, например затухания между изображениями. Хороший плагин для jQuery - это jQuery Cycle Plugin

Если этот плагин не делает этого за вас, или вы хотите сохранить небольшой размер кода, jQuery также имеет встроенные функции анимации. fadeIn () и fadeOut () может представлять интерес.

Нечто подобное может работать лучше.

 <div id="ImageHolder">

</div>

var image - "..."; //Obv actual image in working.

function loadImage() {

choose your image however you want to, preferably a preloaded image.

$('#ImageHolder').fadeOut('fast');
$('#ImageHolder').html(image);
$('#ImageHolder').fadeIn('fast');
setTimeout(loadImage, 10000);
}

Я полагаю, что более короткий способ сделать это может быть: (также delay () может быть необязательным, я просто добавляю его туда, если вам это нужно.)

$('#ImageHolder').fadeOut('fast').html(image).delay('100').fadeIn('slow');

Кроме того, может быть задержка загрузки изображения, если оно не было предварительно загружено. Я не уверен на 100%, как это сделать, так что быстрый поиск в Google придумал это: http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...