1

I have set up a kind of surveillance system, where camera is taking a photo every second and sending this image to server where it overwrites the previous one. On a client side I have a simple javascript with settimeout to load this image every second

$("img").attr("src", "http://mysite/image.jpg?randomString="+new Date().getTime());

But this causes memory leak and eventually the page crashes. How to possibly avoid this? Is caching the problem here? Does the browser caches every new image, every second and that's the reason for the memory leaks?

bukowski
  • 1,893
  • 7
  • 34
  • 54
  • since you have a different "imagename" each time, the browser of course tries to cache that. – Christoph Jun 06 '13 at 07:09
  • By crash, do you mean the browser itself actually crashes? There should be absolutely nothing that you can do on a webpage that will cause the browser to crash. If there is, it's a browser bug. – jcsanyi Jun 06 '13 at 07:10
  • Can you post more of your javascript code? – jcsanyi Jun 06 '13 at 07:14
  • How you know, that this script crash the page! – Pir Abdul Jun 06 '13 at 07:18
  • Are you sure you're using settimeout? To loop every second you should use setinterval. Make sure its set at 1000 and not 1 (common problem). – Jordan Doyle Jun 06 '13 at 07:19
  • 1
    @JordanDoyle actually in many (most) circumstances it's best to call `setTimeout` "recursively" in the callback function than to call `setInterval`. `setInterval` doesn't play nice when tabs are minimized, and doesn't guarantee a minimum time between callbacks. – Alnitak Jun 06 '13 at 07:54
  • Is `$("img").attr(...)` the *only* code in your `setTimeout` callback? – robertklep Jun 06 '13 at 08:30
  • @robertklep yes it is. – bukowski Jun 06 '13 at 09:12
  • Could you just be overloading your browser with requests? If your browser takes more than 1 second to request the image, the number of outstanding requests will pile up; I believe browsers will only open an X amount of connections to the same server. Try waiting for a `load` event on the image before starting a new `setTimeout`. – robertklep Jun 06 '13 at 09:17
  • ([here is a gist](https://gist.github.com/robertklep/5720354) which implements that, Chrome's memory use stays well stable). – robertklep Jun 06 '13 at 09:25
  • try using "async" attribute http://ie.microsoft.com/testdrive/Performance/AsyncScripts/Default.html – Mujtaba Hassan Jun 06 '13 at 10:23

1 Answers1

5

It could be a caching problem because the browser might cache all these images since they have new image names each time (this shouldn't case a crash though).

In this case, set these caching directives in the header and have a look if it fixes the problem:

<!-- disable caching on proxy servers -->
<meta http-equiv="pragma" content="no-cache">
<!-- set expiration date to "immediately" -->
<meta http-equiv="expires" content="0">
<!-- instruct the browser to not cache the webpage -->
<meta http-equiv="cache-control" content="no-cache" />

On the other hand what might be another problem is your javascript. If the server is not able to handle the http requests in time, you queue up a lot of unresolved http requests in the browser. Try setting the timeout to say 5 seconds (= 5000 ms) in this case.

A third possible solution might be to manipulate the image with plain javascript to eliminate the possibility of jQuery memory leaks.

// cache the element once
var img = document.querySelector("img");

// use in setTimeout (Don't create a new Time Object on every call):
img.src = "/image.jpg?randomString="+Date.now();
Christoph
  • 50,121
  • 21
  • 99
  • 128
  • Filling a browser cache will not cause a crash, or any sort of a memory problem. – jcsanyi Jun 06 '13 at 07:16
  • 1
    Also, as far as I know, setting these values on an HTML page will affect the caching of that page, but will do nothing about the images loaded by that page. – jcsanyi Jun 06 '13 at 07:18
  • @jcsanyi can you prove that? you should let the OP decide whether this helps or not. This is a valid answer in every case. and "as far as i know" is not very convincing. – Christoph Jun 06 '13 at 07:18
  • @jcsanyi per se the browser caches all elements on the page it might consider useful caching, also images. THese are the official tags to instruct no caching - whether it ignores or abides by them is up to the browser though. (In fact some browser just ignore these meta tags) – Christoph Jun 06 '13 at 07:23
  • Upvoted to get you to 0. This will help in some cases and since the image is only shown once and there should not be any duplicates the browser shouldnt be caching them anyway. – Jordan Doyle Jun 06 '13 at 07:23
  • The point of a cache is to keep the most recently used items, dropping older items as needed when the cache is full. If caching lots of items caused a crash, then every browser would crash after browsing anywhere for any length of time. – jcsanyi Jun 06 '13 at 07:25
  • I'll give it a try @Christoph and see if it helps. Also I could probably set the no-cache headers from the server side too.\ – bukowski Jun 06 '13 at 07:35
  • @jcsanyi the browser itself doesn't crash, only the page, tab becomes unresponsive... – bukowski Jun 06 '13 at 07:37
  • @fjckls are you using an up-to-date version of jquery? Because old version where known to have memory leaks on ajax calls. – Christoph Jun 06 '13 at 07:46
  • @Christoph, jquery ver is 1.9.1 – bukowski Jun 06 '13 at 08:10
  • @take a look at my edit and see if this helps. Did anything work out yet? – Christoph Jun 06 '13 at 08:11
  • @Christoph, I set the headers and now doing some tests - and it seems that it is working... I'll check a bit more and let you know later. Thanks! – bukowski Jun 06 '13 at 08:18
  • How is changing an image attribute related to memory leaks in AJAX requests? – robertklep Jun 06 '13 at 08:30
  • @robertklep corrected that in the answer, it's not an ajax request but each src change of course triggers an http request. – Christoph Jun 06 '13 at 09:00
  • @fjckls Did you locate the problem of the memory leak? – Christoph Jun 06 '13 at 11:34
  • @Christoph Yes the caching did the trick, I just changed the meta tags, also good points on jquery/javascript optimization. Have my app running all day and no probs. Thanks again! – bukowski Jun 06 '13 at 11:58