开发者

Systematically updating src of IMG. Memory leak

Systematically updating src of IMG. Memory leak.

I am currently updating an image every x sec. A few ways I thought of doing this were as follows:

Take One:

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

Now this works perfectly changes the image but causes a memory leak.

Take Two:

So it is creating DOM elements, so I attempted the following.

<div id="ImageHolder">

</div>

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

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

Now this works but causes a flicker when it changes which is unliked. Now with two images and swapping them at intervals works fine, but I want to stay as low on bandwidth as possible.

Edit 1:

My Code:

<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;
        tot开发者_StackOverflowheright= 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>

Has anyone done something similar and found a working solution, or how can I go about preventing the memory leak / flickering when the image updates?


I believe that your "take one" should work. There should be no memory leak. You're overwriting the src tag every time around - if you hold no other references to old images, they should get garbage collected. I'm seeing this problem in FF and Chrome. Chrome tells me that JS memory usage is constant, the memory must be lost somehwere else. I have opened a Chrome bug: https://code.google.com/p/chromium/issues/detail?id=309543 In case you want to put in your weight as well and maybe star the bug :)


I have used different methods to solve this problem, none of them works. It seems that memory leaks when img.src = base64string and those memory can never get released. Here is my solution.

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 app updating img every 50ms, and memory doesn't leak. Forget about disk usage. Chrome's memory management piss me off.


I have never thought of doing this like your fist method.. interesting. I can imagine that it causes a memory leak because every single image is kept in memory because nothing is actually removed. Thats just a guess though.

I would recomend sticking to the second method but modifying it so solve the flicker, like fading between images. A good jQuery plugin to look at would be the jQuery Cycle Plugin

If that plugin doesn't do it for you or you want to keep the code small, jQuery also has some animation functions built in. fadeIn() and fadeOut() may be of interest.

Something like this might work better.

 <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);
}

I believe a shorter way to do this might be: (also delay() may be optional, I just put it there in case you need it.)

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

Additionally there may be a delay for the image to load if it hasn't been preloaded. I'm not 100% sure how to do that off the top of my head so a quick google seach came up with this: http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript


5 years old question yet it still 'hot' for me, I want to share the very same problem I just faced.

The "take one" approach maybe is the very first approach every programmer used to change the image source, but till now ( 5 years after this question posted ) the problem is still occurred, change the <img> 'src' frequently and you can see on windows task manager that your browser became greedy. The "take two" create flicker, and it is rarely acceptable. Fortunately, html5 comes with <canvas>, so I try to use <canvas> to overcome this problem.

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;

The new problem found, <canvas> different from <img>, it will not automatically resize and 'fit'. We have to manually resize the image to fit the canvas and keep the ratio. Below is my code to resolve the problem

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;

Hope it will help any one who face the same problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜