Closed Bug 637449 Opened 13 years ago Closed 12 years ago

WebGL websites do not release memory after being closed

Categories

(Core :: Graphics, defect)

x86
Windows 7
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 746009

People

(Reporter: ben.r.xiao, Unassigned)

References

()

Details

(Keywords: memory-leak, Whiteboard: [MemShrink:P2])

User-Agent:       Mozilla/5.0 (Windows NT 6.1; rv:2.0b13pre) Gecko/20110228 Firefox/4.0b13pre
Build Identifier: Mozilla/5.0 (Windows NT 6.1; rv:2.0b13pre) Gecko/20110228 Firefox/4.0b13pre

The Flight of the Navigator WebGL demo does not release all memory after being closed. Neither does the Yo Frankie WebGL demo (http://www.glge.org/demos/frankiedemo/).

Both demos increase memory usage by 50 MB.

Reproducible: Always

Steps to Reproduce:
1. Run either WebGL demos
2. Close tab
3. Notice memory usage has jumped 50 MB
Actual Results:  
Some memory is not freed after closing the WebGL page

Expected Results:  
All memory is freed after closing the WebGL page.
Version: unspecified → Trunk
Reproduceable on:
Mozilla/5.0 (Windows NT 6.1; rv:2.0b13pre) Gecko/20110301 Firefox/4.0b13pre

*Note: Wouldn't be this related/similar to the issues reported in the Bug 631494 ?
The memory jumps while playing, but after the tab is closed, each time flushes to a no more than 200 mb level.
Product: Firefox → Core
QA Contact: general → general
Component: General → Graphics
QA Contact: general → thebes
After you close a WebGL tab, the WebGL context object that it uses becomes unreferenced. It will then become freed whenever the JavaScript engine runs its garbage collector.

It is a known issue that unreferenced WebGL contexts are often kept around for quite long before garbage collection actually takes place: see bug 617453.

However, that in itself is not really a bug. It's up to the JS engine to decide when to garbage-collect.

Do you have evidence that anything else than that is happening?
How big are these WebGL contexts? I am literally seeing around 50 MB increases every WebGL page I run and this is unacceptable.

Isn't it pretty trivial to detect when a tab with a WebGL context closes and free that WebGL context?
(In reply to comment #3)
> How big are these WebGL contexts? I am literally seeing around 50 MB increases
> every WebGL page I run and this is unacceptable.

It depends on what the WebGL app did. It could be 50 MB if the WebGL app used big textures or geometric data.

What you say raises a few questions:
 * how long after does this increased memory usage stay around?
 * how do you measure this memory usage? (this is really hard to measure reliably) Why do you trust these values?
 * Are that it's Firefox who's responsible for it and not, say, your operating system?

> 
> Isn't it pretty trivial to detect when a tab with a WebGL context closes and
> free that WebGL context?

I asked this in bug 613494. It doesn't seem trivial at all. But these unused WebGL contexts go away after a while (they should definitely go away quickly if you keep using your browser on other pages, especially on other memory-intensive pages, as the JavaScript engine will eventually garbage-collect dead objects).
> Isn't it pretty trivial to detect when a tab with a WebGL context closes and
> free that WebGL context?

No, because the context can still be used from script even if the tab is closed, as long as script has a reference to it.  And detecting whether script has a reference involves a gc (and actually a cycle collection in this case).

We do plan to make garbage collection more aggressive, and moving to a multi-process architecture will help with the tab-closing thing.  So not all is lost; it'll just take a few months.
(In reply to comment #5)
> > Isn't it pretty trivial to detect when a tab with a WebGL context closes and
> > free that WebGL context?
> 
> No, because the context can still be used from script even if the tab is
> closed, as long as script has a reference to it.  And detecting whether script
> has a reference involves a gc (and actually a cycle collection in this case).

Boris, thanks for this explanation, that's what I was not getting.
(In reply to comment #4)
> What you say raises a few questions:
>  * how long after does this increased memory usage stay around?
>  * how do you measure this memory usage? (this is really hard to measure
> reliably) Why do you trust these values?
>  * Are that it's Firefox who's responsible for it and not, say, your operating
> system?

Well, here's what I did. I ran flight of the navigator and the yo frankie demo. Memory usage increased to about 700 MB. I closed the demos, the memory usage dropped to around 450 MB. I waited for an hour, browsed some other websites, and looked again at my memory usage and it was still around 450 MB. There had to be a GC somewhere within that hour no?

Is there anyway I can force a gc? I tried running your code in the web console, Benoit

netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
          .getInterface(Components.interfaces.nsIDOMWindowUtils)
          .garbageCollect();

but it gave me privilege errors so I am pretty sure I am not supposed to use it in the console. How did you run it?
Try error console - the web console runs with the security privilege of the current web page.
I pasted the code in the error console and it doesn't seem to be doing anything. Nothing is being displayed and memory usage is not going down.
I just put that in a <script> in a html page and loaded it. But that was a file:// URL.
(In reply to comment #7)
> (In reply to comment #4)
> > What you say raises a few questions:
> >  * how long after does this increased memory usage stay around?
> >  * how do you measure this memory usage? (this is really hard to measure
> > reliably) Why do you trust these values?
> >  * Are that it's Firefox who's responsible for it and not, say, your operating
> > system?
> 
> Well, here's what I did. I ran flight of the navigator and the yo frankie demo.
> Memory usage increased to about 700 MB. I closed the demos, the memory usage
> dropped to around 450 MB. I waited for an hour, browsed some other websites,
> and looked again at my memory usage and it was still around 450 MB. There had
> to be a GC somewhere within that hour no?

Surely there had. But you have to realize that on modern OSes, 'measuring memory usage' is very tricky. There's no single metric that you could look up that would tell you the answer.
Well, if you look at Firefox 3.6 and Chrome on the same operating system, their memory usages are comparatively low. What the Windows Task manager reports is what the operating system sees and it will allocate memory for other applications around that.

Even if Firefox 4 was simply allocating more RAM than it needs for caching and memory fragmentation purposes, it is still not usable by other applications on the OS.
So I put a html file on my desktop with the following contents

<html>

<head>
<script type="text/javascript">
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils).garbageCollect();

</script>
</head>

<body>
</body>

</html>


When I opened the file, Firefox warned me that a script was requesting elevated permissions. I clicked Allow and memory usage did not decrease.

I ran flight of the navigator and Yo Frankie. Closing them gave me a memory usage of 350 MB. I ran the script, memory usage did not change.
Depends on: 638549
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: mlk
OK, so, this is interesting. Let's admit for a moment that there's a real leak here. There are 4 layers involved here:

  WebGL code in Firefox ---> ANGLE ---> Direct3D ---> Direct3D Driver
 
The leak could be at any level there. Fortunately, you can replace this chain by

  WebGL code in Firefox ---> OpenGL ---> OpenGL driver

by going to about:config and setting webgl.prefer-native-gl=true. If you have a ATI or Intel card, you will also have to set webgl.force-enabled=true because we block ATI and Intel drivers.

Does this make a difference?
  - if yes, the most likely hypothesis becomes a leak in ANGLE.
  - if no, then I'll start worrying that there may be a leak in our own code.
@ Boris: do you know if such system memory stats are meaningful at all wrt possible leaks? I don't realize the implications of e.g. jemalloc mmapping memory blocks --- would that show up as "used memory"?
Benoit, I don't know....
I tested with webgl.prefer-native-gl=true and it still does not free memory.
@ Benjamin:
  when you have webgl.prefer-native-gl=true, in about:support, what does WebGL renderer say?
NVIDIA Corporation -- GeForce 9600M GT/PCI/SSE2 -- 3.3.0
So, indeed, this is using your OpenGL driver instead of ANGLE.

I will run this in valgrind with a software renderer to see if there is a leak in our WebGL implementation code.

What is the *smallest* WebGL site on which you are seeing a clear and persistent memory usage increase? Asking because running in valgrind is very slow.
Smallest site I can find: http://www.glge.org/demos/hair/

Memory usage started at 150 MB. After 2 runs of the hair demo memory usage went up to 180 MB and won't go back down.
(In reply to comment #21)
> Smallest site I can find: http://www.glge.org/demos/hair/

Currently valgrinding this. Using the NVIDIA driver because OSMesa is apparently not able to run this demo (takes forever to render the first frame).

Details about the procedure are given at:
  https://bugzilla.mozilla.org/show_bug.cgi?id=588918#c21
Valgrind didn't find anything here that could explain the 50 MB leak. We really should try to find a OSMesa-proof demo. I will try with bug 651695.
No longer blocks: mlk-fx5+
Whiteboard: [MemShrink:P2]
Blocks: 657371
Blocks: 678627
QA Contact: thebes → bjacob
Is this still reproducible in Nightly?
This smells very much like memory fragmentation, so duping.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.