Renderer process memory grows and grows |
||||||||
Issue descriptionChrome 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.
,
Feb 8 2017
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?
,
Feb 9 2017
> 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
,
Feb 9 2017
It looks like that our idle GC cleanup mechanism is not kicking in. Assigning to our current memory sheriff.
,
Feb 9 2017
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.
,
Feb 9 2017
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?
,
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.
,
Feb 15 2017
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.
,
Feb 15 2017
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.
,
Feb 15 2017
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?
,
Feb 15 2017
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.
,
Feb 15 2017
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.
,
Feb 15 2017
,
Feb 15 2017
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
,
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.
,
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.
,
Feb 20 2017
Working as intended here as the webpage leaks memory.
,
Feb 21 2017
+ojan Any possible interventions that might deal with this?
,
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?
,
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 |
||||||||
Comment 1 by shrike@chromium.org
, Feb 8 2017