asm.js memory leak with Web Console open.

RESOLVED DUPLICATE of bug 1337585

Status

()

RESOLVED DUPLICATE of bug 1337585
a year ago
a year ago

People

(Reporter: keean, Unassigned)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

a year ago
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36

Steps to reproduce:

Load this page on Firefox 52.1.0 (64-bit) on Linux (may affect other platforms and versions).


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<script>
var mod = (function() {
    function asm(stdlib, foreign, heap) {
        "use asm";

        var heap8u = new stdlib.Uint8Array(heap);

        function inc() {
            var i = 0;
                while ((i|0) < 0x1000000) {
                heap8u[i] = ((heap8u[i] | 0) + 1) | 0;
                i = (i + 1) | 0;
            }
        }

        return {
            inc : inc
        };
    }

    return {
        asm : asm
    };
})();

function Obj() {
    this.heap = new ArrayBuffer(0x1000000);
    var asm = mod.asm({Uint8Array: Uint8Array}, this, this.heap);
    this.asm = asm.inc;
}

function test() {
    for (var i = 0; i < 0x100; ++i) {
        var tmp = new Obj();
        tmp.asm();
    }
    console.log('done.');
}

test();

</script>
</body>
</html>



Actual results:

The page uses about 4.3Gb of RAM that never gets garbage collected (even using an extension that allow GC to be forced). About memory reports:

4,356.28 MB (100.0%) -- explicit
├──4,120.95 MB (94.60%) -- window-objects
│  ├──4,099.09 MB (94.10%) -- top(file:///home/keean/code/practique-html5/dist/test.html, id=37)
│  │  ├──4,098.72 MB (94.09%) -- active/window(file:///home/keean/code/practique-html5/dist/test.html)
│  │  │  ├──4,098.64 MB (94.09%) -- js-compartment(file:///home/keean/code/practique-html5/dist/test.html)
│  │  │  │  ├──4,098.63 MB (94.09%) -- classes
│  │  │  │  │  ├──4,096.02 MB (94.03%) -- class(ArrayBuffer)/objects
│  │  │  │  │  │  ├──4,096.00 MB (94.03%) ── non-heap/elements/wasm
│  │  │  │  │  │  └──────0.02 MB (00.00%) ── gc-heap
│  │  │  │  │  └──────2.61 MB (00.06%) ++ (4 tiny)
│  │  │  │  └──────0.01 MB (00.00%) ++ sundries
│  │  │  └──────0.08 MB (00.00%) ++ (4 tiny)
│  │  └──────0.37 MB (00.01%) ++ js-zone(0x7f78dc12c000)
│  └─────21.86 MB (00.50%) ++ (7 tiny)
├─────95.63 MB (02.20%) -- js-non-window
│     ├──71.24 MB (01.64%) -- zones
│     │  ├──65.83 MB (01.51%) ++ zone(0x7f7919709600)
│     │  └───5.40 MB (00.12%) ++ (7 tiny)
│     └──24.39 MB (00.56%) ++ (2 tiny)
├─────92.25 MB (02.12%) ++ (23 tiny)
└─────47.45 MB (01.09%) -- gfx
      ├──47.00 MB (01.08%) ── heap-textures
      └───0.45 MB (00.01%) ++ (5 tiny)


Expected results:

The object is scoped to the loop, each object should be garbage collected, so total memory usage will depend on memory pressure, but is should not need more than enough space to create one heap buffer. At the end of the program the memory should all be garbage collectable. 

It is important that the memory be collectable as soon as the object holding it goes out of scope, as I am using asm.js in a single-page-app that needs to run without leaking memory.

This used to work fine on earlier versions of Firefox, for example 41.0.2 on Windows 10 (64bit), where there is no memory leak.

At a guess this is related to using WASM buffers for ASM.js
Component: Untriaged → JavaScript Engine
(Reporter)

Comment 1

a year ago
Can I provide any additional detail to help triage this?
Hi keean, thanks for the bug report!

Firefox uses a special technique on 64 bits platforms (which you seem to be using, according to UA). This technique *reserves* 4 GB of memory to improve performance of loads/stores (through signal handlers trickery), but this memory is never committed; only the subset that's used in your actual array buffer is. So the memory isn't really used.

If you go to about:memory and click "minimize memory usage", and then generate a new memory report, does the wasm line disappear? (the extension might not have the possibility to do a full garbage collection)
Component: JavaScript Engine → JavaScript Engine: JIT
Flags: needinfo?(keean)
(Reporter)

Comment 3

a year ago
If you refresh the page, it uses another 4Gb, and another, and keeps doing so on every refresh until swapping makes the computer unusable. 

In my single page app, it never gives up the memory no matter how long I leave it.

I will run the report as soon as I get to a computer, but I can confirm in practical terms Firefox 52 uses more and more memory until it is unusable, whereas Firefox 41 did not do that. So  there is a regression in the sense that it is no longer usable for this kind of application (a single page app, that uses asm.js with different heaps).
Flags: needinfo?(keean)
I've just tried with Nightly and Release (linux64); after a "minimize memory usage" click, the memory usage actually falls down. So either there's another platform-specific problem, or the memory pressure event isn't sent/handled correctly.

Luke, any idea?
(Reporter)

Comment 5

a year ago
Minimising does not make any difference for me.
(Reporter)

Comment 6

a year ago
Its weird, it seems to depend on what else is running in the browser. If I start a fresh browser, then it leaks the memory,
(Reporter)

Comment 7

a year ago
I have been experimenting with this for a while. On my 64bit Linux system it nearly always leaks the memory, and never recovers, and clicking "Minimize memory usage" does not help, however just one time it seemed to garbage collect properly, keeping the size down and with no need to even click "Minimize memory usage".

This testing was done on the Extended Support Release (52.1).
(Reporter)

Comment 8

a year ago
It seems like the situation is better on Nightly, and most of the time Nightly if collecting the memory, and only occasionally leaking it, which is the reverse of the situation with 52.1 the Long Term Support version, which seems to nearly always leak the memory, to the point the computer quickly becomes unusable.
(Reporter)

Comment 9

a year ago
Made a bit of a breakthrough, Nightly seems to leak the memory when the "Web Console" is open. With the web console open it reliably leaks 4G for each page refresh. If the console is closed the leaked memory remains leaked, and "Minimize Memory Usage" does not recover it, however no more memory is leaked with the "Web Console" closed again. I will check with the LTS version now.
(Reporter)

Comment 10

a year ago
I have confirmed the behaviour is the same in version 52.1 (the Long Term Support version), the memory is leaked only if the "Web Console" is open. Once the memory is leaked it seems the only way to recover it is to close the tab.

So to reproduce the issue, open the "Web Console" before downloading or refreshing the page.
(Reporter)

Updated

a year ago
Summary: asm.js memory leak → asm.js memory leak with Web Console open.
Yes, this is a long-standing problem with the web console and not specific to asm.js.
Status: UNCONFIRMED → RESOLVED
Last Resolved: a year ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1337585
(Reporter)

Comment 12

a year ago
It doesn't affect the asm.js in 41.0.2 though, it only seems an issue with the new WASM buffers that asm.js has started using?
Possibly, or the web console behavior changed.
(Reporter)

Comment 14

a year ago
Is it worth trying to track down the version where the behaviour changed?
If we have Web Console leaking the whole window, and the asm.js heap is reachable from the window's global, then it's not surprising you're seeing this leak, so I'm not sure there is anything to fix here until the underlying bug 1337585 is fixed.
(Reporter)

Comment 16

a year ago
Was the old asm.js (pre WASM) heap not reachable from the window object then?
I guess not.  Another interesting experiment would be to comment out of the 'use asm' (so it's just running as normal JS), inflate the ArrayBuffer size to 1gb (so it's easier to notice) and see if that 1gb stays leaked in the same manner as the asm.js.
(Reporter)

Comment 18

a year ago
It would appear that without the "use asm" it does not leak the memory, even if the Web Console is open. So it appears to be something special about a WASM buffer and the Web Console.
You need to log in before you can comment on or make changes to this bug.