Open Bug 1220488 Opened 9 years ago Updated 2 years ago

High memory usage when buffering multiple videos

Categories

(Core :: Audio/Video: Playback, defect, P3)

41 Branch
defect

Tracking

()

UNCONFIRMED

People

(Reporter: sergroj, Unassigned)

Details

(Whiteboard: [MemShrink:P2])

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Build ID: 20150916094008

Steps to reproduce:

Go to https://www.manyvids.com/Vids/ (Warning: NSFW!!)
- Open any 5 videos with middle click.
- Close these tabs as soon as they are fully loaded (indicated by their icons).
- Repeat the process for another 5 videos.
- Repeat the process for a couple more iterations.
(opening more than 5 videos at once speeds things up)


Actual results:

- Memory usage growing very fast.
- Most of that memory gets freed if FF is given time to digest it, but apparently not all of it. The problem accumulates the more you repeat the process.
- Typical results of FF memory leaks occur: slowness, hanging, eventually rendering black screen and crashing.
Notes: Under normal usage with normal web sites accumulation of leaks plays a bigger role, because FF would run for hours. Too bad it turned out this site doesn't make leaks as obvious as I initially though.


Expected results:

- Memory shouldn't get consumed so fast.
- Memory should get freed completely.
I'm reluctant to ask my colleagues to start browsing non-worksafe sites to reproduce a memory leak, but if you could give us some technical details about the videos in question that might be helpful.

Can you try reproducing this without addons, on the current release of Firefox? And could you provide some technical details (media type, encoding, other) about the videos themselves?
Correction: Middle-clicking Clone once won't be enough to bring troubles. 3 middle clicks in a row would cause a crash.
That is not a safe for work page at all.
OK, I'm going to try to reproduce this running behind rr, and if not I'll see what else I can do. If it depends on the specific content, I'll see if I can gin up an equivalent that's a it more safe work and a bit less anatomically enthusiastic.
Ah, images! Here, this should be fully safe:

<!DOCTYPE HTML>
<html>
<head>
	<title>Video test</title>
	<meta charset="utf-8">
</head>
<body>
<a href="#">Clone</a>
<br/>
<br/>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>



<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>


<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>


<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>


<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.ogg"/> 
 
<object type="application/x-shockwave-flash" data="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv">
 
<param name="movie" value="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.flv"/>
<param name="flashvars" value="controlbar=over&amp;file=https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4"/>
 

</object>
</video>





</body>
</html>
Removed the clutter, made exactly 20 video tags. Funny thing is, it's not specific to this video. It makes FF eat memory twice as fast as a video from w3c example http://www.w3schools.com/html/html5_video.asp. The trailer from porn site takes roughly 85MB of allocated virtual memory for each video tag, http://www.w3schools.com/html/mov_bbb.mp4 from w3c takes about 40MB, which is still a lot considering how small the videos themselves are.

<!DOCTYPE HTML>
<html>
<head>
	<title>Video test</title>
	<meta charset="utf-8">
</head>
<body>
<a href="#">Clone</a>
<br/>
<br/>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

<video controls preload="auto" data-setup='{"controls": false, "preload": "auto"}'>
<source src="https://d2adpaynhf6x63.cloudfront.net/video_intro/MVclip.mp4" type="video/mp4"/> 
</video>

</body>
</html>
Component: Untriaged → SocialAPI
Component: SocialAPI → WebRTC: Audio/Video
Product: Firefox → Core
Whiteboard: [MemShrink]
Component: WebRTC: Audio/Video → Audio/Video: Playback
Thanks for the reduction build. Dan, relevant to your idle decoder cleanup, maybe?
Flags: needinfo?(dglastonbury)
Priority: -- → P2
Behaviour is not so bad for me in 44 with the page in comment 7. Up to ~350MB after 5-10 reloads. So it might be better in more recent versions of Firefox, as well.
After one run on trunk:

> Web Content (pid 5166)
> Explicit Allocations
> 
> 449.77 MB (100.0%) -- explicit
> ├──424.79 MB (94.45%) ── heap-unclassified
> ├───11.75 MB (02.61%) ++ js-non-window
> ├────7.06 MB (01.57%) ++ heap-overhead
> └────6.17 MB (01.37%) ++ (18 tiny)

That's a *ton* of heap-unclassified. I'll spin up a DMD build to see if I can track down what's going on.
Attached file Test case
Test case from comment 7.
Attached file dmd.txt.bz2
DMD indicates most of the unaccounted memory is coming out of libav, perhaps sitting in a decode buffer?
The memory usage still seems rather high, perhaps we shouldn't decode all videos at once? I'll file a follow up for the memory reporting side of this.
Whiteboard: [MemShrink] → [MemShrink:P2]
I updated the summary to be more specific. Please change if I misunderstood something.
Summary: FireFox memory leaks and issues, rampant on a particular site → High memory usage when buffering multiple videos
(In reply to Mike Hoye [:mhoye] from comment #4)
> That is not a safe for work page at all.

that is an understatement !
(In reply to Eric Rahm [:erahm] from comment #13)

> DMD indicates most of the unaccounted memory is coming out of libav, perhaps
> sitting in a decode buffer?

FFmpeg isn't used on Windows which is what the original report was on.

You may have found another bug there (libavcodec 54 from LibAV is fairly old and AFAIK was only used on Ubuntu 14.04)
(In reply to Eric Rahm [:erahm] from comment #12)
> Created attachment 8691597 [details]
> dmd.txt.bz2
> 
> DMD indicates most of the unaccounted memory is coming out of libav, perhaps
> sitting in a decode buffer?

The backtrace provided here do not make much sense.

av_parser_close is only ever used for h264. Yet it calls a flac related function. This indicates memory corruption with the parser pointer.
(In reply to Jean-Yves Avenard [:jya] from comment #16)
> (In reply to Eric Rahm [:erahm] from comment #13)
> 
> > DMD indicates most of the unaccounted memory is coming out of libav, perhaps
> > sitting in a decode buffer?
> 
> FFmpeg isn't used on Windows which is what the original report was on.
> 
> You may have found another bug there (libavcodec 54 from LibAV is fairly old
> and AFAIK was only used on Ubuntu 14.04)

Yes this was on Ubuntu 14.04 LTS. I can file a separate bug if you'd like.

(In reply to Jean-Yves Avenard [:jya] from comment #17)
> (In reply to Eric Rahm [:erahm] from comment #12)
> > Created attachment 8691597 [details]
> > dmd.txt.bz2
> > 
> > DMD indicates most of the unaccounted memory is coming out of libav, perhaps
> > sitting in a decode buffer?
> 
> The backtrace provided here do not make much sense.
> 
> av_parser_close is only ever used for h264. Yet it calls a flac related
> function. This indicates memory corruption with the parser pointer.

It's possible the symbols aren't correct for my system install.
I can't work out how to use the test case in comment 7. It seems quite
different to the original site.

Testing on the original site I did the following (Mac, e10s build):

- middle click on a bunch of videos to open them in new tabs

- close those tabs

- measure in about:memory. I got some detached windows but they went away after
  not too long.

- Close the original site so about:memory is the only tab open. The content
  process is killed, leaving just the chrome process, which has this:

> 381.22 MB (100.0%) -- explicit
> ├──171.26 MB (44.92%) -- gfx
> │  ├──171.04 MB (44.87%) ── heap-textures
> │  └────0.22 MB (00.06%) -- (4 tiny)
> │       ├──0.10 MB (00.03%) ── font-list
> │       ├──0.09 MB (00.02%) ── font-shaped-words
> │       ├──0.03 MB (00.01%) ── font-charmaps
> │       └──0.01 MB (00.00%) ── font-cache
> ...
>   870.66 MB ── resident

The "gfx/heap-textures" bounces around, going as low as 77 MiB, but I can't get it to go away. "explicit" is much lower than "resident", which is non-typical.

It's all a bit weird. Definitely something funny going on with the videos.
Whiteboard: [MemShrink:P2] → [MemShrink:P1]
Flags: needinfo?(dglastonbury)
Mass change P2 -> P3
Priority: P2 → P3
This seems like it's not prevalent enough to warrant a P1, dropping to P2.
Whiteboard: [MemShrink:P1] → [MemShrink:P2]
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: