Wednesday, November 27, 2013

Do not allocate Typed Arrays too frequently, or your browser will die OOM

The following code causes the browsers' JavaScript runtime to crash (or allocate gigabytes of memory) when the array length is only around 1MB to 2MB (reproducible on Google Chrome 30.0.1599.101 / Safari 6.1 (8537.71) running on OS X 10.8.5; Mozilla Firefox 25.0.1 does not have the problem).

current length of Uint8Array is <input id="arrlen"> bytes.
<script>
var arr = new Uint8Array(12345);
function doit() {
  for (var i = 0; i < 100; ++i) {
    arr = new Uint8Array(arr.length + (Math.random() * 500 | 0));
  }
  document.getElementById("arrlen").value = arr.length;
}
setInterval(doit, 1);
</script>

test link

My understanding is that historically, this is due to the fact that Typed Arrays were defined outside of the ECMAScript specification and that it was implemented outside of the JavaScript VMs. Memory chunks that are used to store the elements of the arrays are allocated outside of the VM heap, and GC tracks only the reference to the array elements. Thus the pressure against GC is tiny per each allocation even though the pressure against malloc might be high. And the outcome is that malloc gives up well before GC starts to free the typed arrays that are no longer used.

I had thought that the problem had been fixed a while ago, but it still seems to exist. And although I believe that it will be fixed sooner or later I am writing this weblog so that, until then, others who fall into the pitfall can understand the problem.

PS. opened the issue on the Chromium issues tracker.

9 comments:

  1. Your blog was too good. i really appreciate with your blog.Thanks for sharing.
    IPL 2016 Schedule time table
    IPL 2016 Schedule release date

    ReplyDelete
  2. Look out for instance variables misused as method parameters

    In almost all cases, the objects allocated within a method should be discarded by the end of that method (excluding return values, of course). As long as you use local variables to hold all these objects, this rule is easy to follow. However, it's tempting to use instance variables to hold method data, particularly for methods that call a lot of other methods, and thereby avoiding the need for large parameter lists.

    Doing this won't necessarily create a leak. Subsequent method calls should re-assign the variables, allowing the objects to be collected. But it raises your memory requirements unnecessarily (sometimes enormously) and makes debugging more difficult (because you have unexpected objects in memory). And from a general design perspective, when I've seen code like this it has always indicated that the method really wants to be its own class.

    unblocked games at school

    ReplyDelete