New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 722522 link

Starred by 12 users

Issue metadata

Status: Started
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug


Participants' hotlists:
Hotlist-1

Previous locations:
webrtc:7633


Sign in to add a comment

Memory leak with gUM

Reported by rajkumar...@gmail.com, May 11 2017

Issue description

What steps will reproduce the problem?
Created a sample page which does only gUM (audio only) and once the stream is obtained just stop all the tracks and set stream to null - With this there's a memory increase for every iteration.

What is the expected result?
Memoryleak should not be there.

What do you see instead?
With this there's a memory increase for every iteration and it never reduces. Because of this we are seeing crash. Exponential increase in memory from 20MB to 155MB within 10minutes with each iteration at a time interval of 2seconds.


What version of the product are you using? On what operating system?
Tested this in Chrome 53+ version onwards till version 57. Windows

Please provide any additional information below.



 
Please find the attached test code 
gUM_test.7z
31.3 KB Download
Appreciate if we could get some early feedback on this, as it has become blocker in our production environment.
Project: chromium
Moved issue webrtc:7633 to now be issue chromium:722522.
Components: Blink>GetUserMedia
Labels: OS-Windows
Thanks for the report. The sample page seems to only be requesting audio.
Labels: Needs-Milestone
Yes, That's right, we have observed memory leak with audio only streams. With video it has not been tested yet.

Comment 7 by guidou@chromium.org, May 16 2017

Owner: guidou@chromium.org
Status: Assigned (was: Unconfirmed)
Will take a look and reassign if necessary.
We have observed the memory leak as well as device access failure with the error "TrackStartError" with the same code.
Memory usage crosses 1GB after around 2000 GetUserMedia calls.
Attaching the chrome debug log captured when device access fails with "TrackStartError".The failure first occurred after successfully acquiring the stream 2681 times.Memory usage was around 1.6GB after 9000+ times.
chrome_debug.log
11.3 MB View Download
Attaching the chrome debug log captured when device access fails with "TrackStartError".The failure first occurred after successfully acquiring the stream 2681 times.Memory usage was around 1.6GB after 9000+ times.
We are experiencing same issue with our application and the application crashes after few hours. Chrome team, can you please update on the status of this issue. Thanks..
Is this leak observed only on Windows, or is it reproducible on other platforms as well?

Comment 14 by bak...@gmail.com, May 25 2017

Windows 10
- Observed memory leak with gUM_test Code

Windows 2008 R2 Virtual Machine
- Launched Chrome with fake Media options 
(Google Chrome version -58.0.3029.110)
- ran gUM_test Code
- encountered device access failure with "TrackStartError" after 2681 iterations of gUM calls
- Continued the test upto 9000+ times. Memory usage was around 1.6GB
- Attaching Chrome_debug logs and Console output
chrome_debug.log
11.3 MB View Download
console_screenshot.png
118 KB View Download
Components: -Blink>GetUserMedia Blink>JavaScript>GC
Labels: -OS-Windows OS-All
Owner: ----
Status: Available (was: Assigned)
I tried the repro page and I found out that there is no leak, even if it looks like one.
For easier reproduction I modified the page slightly and made it available at https://jsfiddle.net/p2LLmz2e/5/

That modified script tries to run gc() (if available) after every track stop.

If Chrome is run with the --js-flags="--expose-gc"  commmand-line flag, gc() is exposed and the page's memory consumption remains flat. Otherwise, memory continues to grow indefinitely until a gc actually runs.

Switching the component to Blink>JavaScript>GC, to see if this is is actually a GC bug or expected behavior.
Cc: guidou@chromium.org
Status: Untriaged (was: Available)
Owner: mlippautz@chromium.org
Status: Assigned (was: Untriaged)
assigning to current memory sheriff
Cc: -guidou@chromium.org mlippautz@chromium.org
Owner: guidou@chromium.org
Status: Untriaged (was: Assigned)
I just reproduced this on ToT. The memory trace is attached.

From the local V8 GC log I see that there is no memory traffic visible for v8. External memory reported is in the range of ~5M for 4k iterations on the jsfiddle repro. In the trace I see high malloced memory. Calling V8's GC helps, so I would assume that we lack proper accounting for external memory.

guidou@: Can you have a look, please?
Components: -Blink>JavaScript>GC Blink>GetUserMedia
Feel free to reassign if you feel differently.

For completeness: The leak is in the renderer malloc bucket and 4k iterations result in ~2GB of leaked memory.
Cc: -mlippautz@chromium.org guidou@chromium.org
Components: Blink>JavaScript>GC
Owner: mlippautz@chromium.org
Status: Assigned (was: Untriaged)
mlippautz@: I did not quite understand your explanation. Can you explain further how explicit calls to gc() can fix an external memory leak?

If gc() is called explicitly after stopping the track (see https://jsfiddle.net/guidou/p2LLmz2e/7/), the script can run with flat memory consumption for many iterations. On my system top reports a flat ~200K after 10K iterations.

Without the explicit call to gc(), memory grows as you report. On my system top reports ~2.5GB after 4K.

Cc: haraken@chromium.org u...@chromium.org
JavaScript objects can keep alive C++ memory via Bindings, i.e., as long as we don't trigger a GC in V8, the JS object will stay alive and thus keep all transitively reachable blink memory alive. Since C++ memory bucket is high in this case (see trace), I assume that there's some C++ object held alive by JS. Again, it is not the JS heap that is leaking here!

Now, V8 GC scheduling can only take the JS objects into account for its scheduling. If there are only a few JS objects created, then there will be no V8 GC scheduled, since the system thinks it is not necessary. Since this would keep alive any C++ memory that is referenced from JS objects, there exists an additional API (AdjustAmountOfExternalMemory) that is used by Bindings and in general on the Blink side to inform V8 of how much memory is kept alive by JS. Presumably this accounting is missing in this case, which means that V8 will not schedule a GC and we will leak C++ memory.

Who are the OWNERS of the API involved here?
Cc: -guidou@chromium.org mlippautz@chromium.org
Owner: guidou@chromium.org
Thanks a lot for the the explanation!

So there is no leak. The problem is that JavaScript's GC believes it has allocated little memory because the bulk of the consumed memory comes from the C++ objects implementing the functionality of the JS objects. 
The fix is then to use this AdjustAmountOfExternalMemory API so that JavaScript's garbage collector is aware of the real memory pressure.

Since I am one of the OWNERS of getUserMedia() and related classes, I'll take a look at how that works and prepare a patch.
Thanks for having a look. Let me know if you require more help and/or a review.
Issue 731179 has been merged into this issue.
Cc: guidou@chromium.org
Owner: orphis@chromium.org
Cc: -guidou@chromium.org
Owner: guidou@chromium.org
Cc: guidou@chromium.org
Owner: orphis@chromium.org
Status: Started (was: Assigned)
 Issue 788405  has been merged into this issue.

Sign in to add a comment