11

Let's make it immediately clear: this is not a question about memory leak! I have a page which allows the user to enter some data and a JavaScript to handle this data and produce a result. The JavaScript produces incremental outputs on a DIV, something like this:

(function()
{
   var newdiv = document.createElement("div");
   newdiv.innerHTML = produceAnswer();
   result.appendChild(newdiv);
   if (done) {
      return;
   } else {
      setTimeout(arguments.callee, 0);
   }
})();

Under certain circumstances the computation will produce so much data that IE8 will fail with this message:

not enough storage when dealing with too much data

The question is: is there way I can work out how much data is too much data?

as I said there is no bug to solve. It's a genuine out of memory because the computation requires to create too many html elements.

My idea would be to run a function before executing the computation to work out ahead if the browser will succeed. But to do so, in a generic way, I think I need to find the memory available to my browser.

Any suggestion is welcome.

Zo72
  • 14,593
  • 17
  • 71
  • 103

4 Answers4

7

Javascript (in the browser) is run in a sandbox, which means that it is fenced-off from accessing things that could cause security issues such as local files, system resources etc - so no, you can't detect memory usage.

As the other answers state, you can make the task easier for the browser by pausing between implementations or using less resource-intensive code, but every browser has its limits.

Freddy Tuxworth
  • 396
  • 1
  • 4
  • 9
Adam Hopkinson
  • 28,281
  • 7
  • 65
  • 99
3

Have a play with this...

document.write(performance.memory.jsHeapSizeLimit+'<br><br>');
document.write(performance.memory.usedJSHeapSize+'<br><br>');
document.write(performance.memory.totalJSHeapSize);
1

A loop will use less memory than recursion.

   do
   {
     var newdiv = document.createElement("div");
     newdiv.innerHTML = produceAnswer();
     result.appendChild(newdiv);
   } while (!done);

You could also put some upper limit on the number of answers produced.

   var answerCount = 0;
   do
   {
     var newdiv = document.createElement("div");
     newdiv.innerHTML = produceAnswer();
     result.appendChild(newdiv);
   } while (!done && answerCount++ < 1000);
Doug Domeny
  • 4,410
  • 2
  • 33
  • 49
  • Passing arguments.callee to setTimeout invokes the function again, but you are correct, it is not strictly recursion because the setTimeout allows the calling function to return (at least it should, but perhaps the delay=0 is optimized to call immediately, in which case it would be recursion). Using a loop with a counter will still help and the code will be easier to read. – Doug Domeny Jan 08 '10 at 22:51
  • even with delay=0 you don't have recursion. – Zo72 Apr 29 '13 at 09:16
0

I suspect having a 0 timeout delay is the problem - it's trying to re-run instantly. Try increasing this.

graphicdivine
  • 10,937
  • 7
  • 33
  • 59
  • no it's not. the 0 timeout delay is a well known technique. google around if you don't believe me. – Zo72 Jan 08 '10 at 14:10