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

Issue 690102 link

Starred by 4 users

Issue metadata

Status: WontFix
Owner:
Closed: Feb 2017
Cc:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 2
Type: Bug



Sign in to add a comment

Renderer process memory grows and grows

Project Member Reported by shrike@chromium.org, Feb 8 2017

Issue description

Chrome Version: 56.0.2924.87 Stable
OS: macOS 10.12.3

What steps will reproduce the problem?
(1) Go to http://www.math-aids.com/cgi/pdf_viewer_1.cgi?script_name=add_5min.pl&A1_0=1&A1_1=1&A1_2=1&A1_3=1&A1_4=1&A1_5=1&A1_6=1&A1_7=1&A1_8=1&A1_9=1&A1_10=1&A1_11=1&A1_12=1&A1_13=1&A1_14=1&A1_15=1&A1_16=1&A1_17=1&A1_18=1&A1_19=1&A1_20=1&A2_7=1&probs=60&language=0&memo=&answer=1&x=166&y=27
(2) Repeatedly simulate memory pressure with sudo memory_pressure -S -l critical -s 10; also let machine sleep overnight
(3) Check memory stats in Task Manager

There's a lot happening on this page, and as a result it chews up battery, but it also seems to chew up memory. When you first go there, Task Manager Memory starts off around 220M and Private around 150M, but grows after that. Over the past month I've gotten the sense that memory pressure may make memory use worse, so I experimented with simulating memory pressure. I would wait about 10 minutes and then simulate memory pressure, and then wait a bit for the browser to respond (the memory pressure signal is delayed on the Mac). Each time I could see the renderer process's memory use jump dramatically.

These traces were taken with --enable-heao-profiling enabled. I didn't check that many options in the trace setup window so there's not tons of detail :-/. Relevant pid is 2465.


trace_math-aids-1 was taken sometime shortly after opening the page and simulating memory pressure. I didn't note the Task Manager memory readings unfortunately - Memory was probably in the mid 400M.

trace_math-aids-2-500 was taken after waiting about 9 minutes and then simulating memory pressure - at that point the Memory column had jumped to 500M.

trace_math-aids-afterwake-780 was taken this morning after waking my machine from sleep (so an entire day had gone by). Task Manager Memory column was at 780M (!!).

trace_math-aids-after-memorypressure-890-750p was taken shortly after that, after simulating memory pressure. At this point Task Manager Memory had grown to 890M, and Private Memory to 750M.

 
trace_math-aids-1.json.gz
9.1 MB Download
trace_math-aids-2-500.json.gz
4.2 MB Download
trace_math-aids-afterwake-780.json.gz
8.5 MB Download
trace_math-aids-after-memorypressure-890-750p.json.gz
6.4 MB Download
Cc: erikc...@chromium.org
Cc: primiano@chromium.org
Thanks for doing this investigation. It looks like the v8 heap is growing the most substantially for that renderer, not sure if this is intended and/or functioning correctly.

primiano@, who's most knowledgeable about the intersection of v8 and memory profiling?
Cc: hpayer@chromium.org
> primiano@, who's most knowledgeable about the intersection of v8 and memory profiling?
+hpayer. when he looks at memory, JS objects garbage collect themselves in fear :P

trace_math-aids-afterwake-780.json is quite interesting. also because thankfully this seems to have gc object stats also.

The old_space is 443 MB large (ignore the effective_size *).
at the same time it claims that allocated_objects_size = 291 MB (which suggests that there are 152 MB wasted in the old space).
also, more interestingly, the gc object tracker reports only 181 MB at last GC.
What is the difference between 291 - 181 = 110 MB? Are those objects created in the timeframe (last gc, time of the dump?). Or is the allocated_object_size rounding up too much in the dump?


* it's a weird accounting issue w.r.t object_stats_at_last_gc to avoid double counting of old space and obj stats sizes
Screen Shot 2017-02-09 at 12.31.07 PM.png
58.4 KB View Download
Owner: mlippautz@chromium.org
Status: Assigned (was: Untriaged)
It looks like that our idle GC cleanup mechanism is not kicking in. Assigning to our current memory sheriff.
Here's what's going on: The page never goes idle as it *always* calls JS at some rate that is above the defined idle threshold. We are thus in performance mode, resulting in a growth factor of 4x, meaning that we'd only do a GC if we grow the heap by 4x. This is basically working as intended as we want to provide good performance for active JS apps.

#13: I suspect that the dump is not doing a GC, so (like you suggested) this should be the size of the objects created in the timeframe last gc till time of dump.
Some questions:

What is the idle threshold rate?

Re: the GC on 4x heap growth, does "x" ever get reset or is it some starting value? In the last trace (trace_math-aids-after-memorypressure-890-750p) how close is it to a GC?

I also thought that the browser purges memory on critical memory pressure events - it seems like such a purge would trigger a GC?

Comment 7 by shrike@chromium.org, Feb 15 2017

Today I found this page had grown to 1GB in the Task Manager Memory column:

http://appleinsider.com/articles/16/11/14/review-apples-late-2016-15-macbook-pro-with-touch-bar

I'm thinking this is another case of the page being so active that GC doesn't kick in. Or maybe not - I don't know V8's criteria for deciding that a page is too active for GC. In general that behavior seems like a problem.

Is this page in the background? We shouldn't be treating a background page as in "performance" mode, it should be forced idle if it's been in the background a while.
Cc: u...@chromium.org jochen@chromium.org
The page runs in foreground.

I ran this today in M58 (recent Canary) and on Safari. Both browser show memory consumption going up over time. 

- Safari started at ~200M overall and is at ~678M (w/ 67.7M showing as compressed) after ~3h.
- Canary (M58) in the same timeframe is now at 2G overall with ~1.5G used (~1.7G) committed JS.

The page is allocating at a constant rate which prohibits the idle GC to kick in. However, we have a safety net that performs full GCs after ~100s. I see this GCs happening but they fail to free up any memory. I also see context disposal GCs.

Sample log entry from --trace-gc --trace-gc-verbose after ~3h:

[75010:0x7fcb5a814600]  6247311 ms: Mark-sweep 1410.8 (1586.6) -> 1342.9 (1586.6) MB, 2039.6 / 3.3 ms  context disposal GC in old space requested
[75010:0x7fcb5a814600] Memory allocator,   used: 1624640 KB, available: 505280 KB
[75010:0x7fcb5a814600] New space,          used:   1085 KB, available:  15026 KB, committed:  32768 KB
[75010:0x7fcb5a814600] Old space,          used: 1198253 KB, available:    700 KB, committed: 1382792 KB
[75010:0x7fcb5a814600] Code space,         used:  23222 KB, available:      0 KB, committed:  26604KB
[75010:0x7fcb5a814600] Map space,          used: 146429 KB, available:      0 KB, committed: 174100 KB
[75010:0x7fcb5a814600] Large object space, used:   6149 KB, available: 504759 KB, committed:   6208 KB
[75010:0x7fcb5a814600] All spaces,         used: 1375140 KB, available: 520486 KB, committed: 1622472KB

Old space memory is leaking here (1.1G) but surprisingly we also have 146M (!) in maps. 

There's definitely a leak somewhere here. However, I am not yet convinced that it's Chrome since Safari is also having troubles here.
Cc: verwa...@chromium.org
if you use the devtools heap profiler, it looks like the page is constantly allocating stuff.

Adding Toon as 146M of maps sounds like something we should look into regardless.

Michael: can you do a breakdown of what types of objects we have in old space?
I am onto this right now. Forgot that we have object stats integrated into tracing now and already closed the bloated page...

Will report back with a breakdown of the top consumers in old space.
I managed to get the objects stats from a run that leaks.

Top consumers in old space are descriptor arrays, which shouldn't be a surprise given that maps are leaking (?). 

UNKNOWN FixedArray is unfortunately also pretty high up. Will take a look separately. Since we require explicit walking in object stats this one is expected to be out of sync every once in a while.
heap-stats-math-aids.com.png
436 KB View Download
trace_math-aids-com.json.gz
24.0 KB Download
For completeness, the overall top consumers are:

FUNCTION_TEMPLATE_INFO_TYPE 
DESCRIPTOR_ARRAY
UNKNOWN (catch all for non-categorized memory)
DICTIONARY_PROPERTIES
PROPERTY_CELL_TYPE

Comment 15 by u...@chromium.org, Feb 16 2017

The heap snapshot shows thousands of Window objects after 30 minutes.

I noticed suspicious retaining paths that look like cross-context leaks (see screenshot). The path goes through ThrowTypeError() contest => slow_template_instantiations_cache() => prototype of some object => Window object. 


math-aid.png
89.5 KB View Download

Comment 16 by u...@chromium.org, Feb 16 2017

[The retaining path in #15 is not correct since it contains a cycle. I filed a bug for DevTools:  crbug.com/69325 ]

After some debugging I am convinced that the memory growth is caused by memory leak in the webpage itself.

The webpage periodically adds new iframes into the DOM tree without removing the old iframes. The iframes load Ads from different sources.

You can verify it by inspecting the webpage elements and searching for "iframe". Or by running window.document.getElementsByTagName("iframe").length in console.

In my local run the number of iframes started at 30 and reached 100 in about 20 minutes. Since each iframe creates a separate V8 native context, the large memory usage in V8 is expected. Garbage collection cannot free memory because iframes are live as they are directly attached to the DOM tree.

So I would say this is WAI from V8 GC point of view.
Status: WontFix (was: Assigned)
Working as intended here as the webpage leaks memory.
Cc: ojan@chromium.org
+ojan

Any possible interventions that might deal with this?

Comment 19 by nduca@chromium.org, Feb 22 2017

Maybe we should have a s-l or trim-level discussion about how to handle and recover more gracefully from webpages that have bad memory behavior?

Comment 20 by ojan@chromium.org, Feb 22 2017

I'll note that this page basically pauses when backgrounded. So this is about mitigating foreground tab abuses. The best idea I've got so far is to expose UX to users when pages are being abusive in areas the user can't obviously identify. 

https://docs.google.com/document/d/1y8uUNUcBc_gTZidOIuMIbNFLGI3dz5XVMlPDRwbVEKE/edit#heading=h.an2m8ut3jfzi (Sorry for the internal-only link.)

Sign in to add a comment