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

Issue 685452 link

Starred by 4 users

Issue metadata

Status: WontFix
Owner:
Closed: Aug 2017
Cc:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Feature

Blocking:
issue 676082



Sign in to add a comment

2MiB increase in PerformanceResourceTiming after 3 days of facebook.com

Project Member Reported by ssid@chromium.org, Jan 26 2017

Issue description

Keeping Facebook open for 3 days causes 2MiB increase in blink::PerformanceEntry objects in BlinkGC dump provider.

Stack trace of allocation:
↳ƒv8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*)
↳ƒv8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<true>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments)
↳ƒv8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&))
↳ƒblink::V8XMLHttpRequest::constructorCallback(v8::FunctionCallbackInfo<v8::Value> const&)
↳ƒblink::XMLHttpRequest::create(blink::ScriptState*)
blink::PerformanceEntry
↳ƒblink::scheduler::TaskQueueManager::DoWork(base::TimeTicks, bool)
↳ƒblink::scheduler::TaskQueueManager::ProcessTaskFromWorkQueue(blink::scheduler::internal::WorkQueue*, blink::scheduler::LazyNow, base::TimeTicks*)
↳ƒbase::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*)
↳ƒcontent::ResourceSchedulingFilter::DispatchMessage(IPC::Message const&)
↳ƒcontent::ResourceDispatcher::OnMessageReceived(IPC::Message const&)
↳ƒcontent::ResourceDispatcher::DispatchMessage(IPC::Message const&)
↳ƒbool IPC::MessageT<ResourceMsg_RequestComplete_Meta, std::tuple<int, content::ResourceRequestCompletionStatus>, void>::Dispatch<content::ResourceDispatcher, content::ResourceDispatcher, void, void (content::ResourceDispatcher::*)(int, content::ResourceRequestCompletionStatus const&)>(IPC::Message const*, content::ResourceDispatcher*, content::ResourceDispatcher*, void*, void (content::ResourceDispatcher::*)(int, content::ResourceRequestCompletionStatus const&))
↳ƒcontent::ResourceDispatcher::OnRequestComplete(int, content::ResourceRequestCompletionStatus const&)
↳ƒcontent::WebURLLoaderImpl::Context::OnCompletedRequest(int, bool, bool, base::TimeTicks const&, long, long)
↳ƒblink::ResourceFetcher::handleLoaderFinish(blink::Resource*, double, blink::ResourceFetcher::LoaderFinishType)
↳ƒblink::PerformanceBase::addResourceTiming(blink::ResourceTimingInfo const&)
↳ƒblink::GarbageCollected<blink::PerformanceEntry>::operator new(unsigned long)

Adding keishi to triage or re-assign. Thanks! Please take teh trace from issue 685449
 

Comment 1 by ssid@chromium.org, Jan 26 2017

Labels: Performance-Memory

Comment 2 by ssid@chromium.org, Jan 26 2017

The trace shows there are 16k objects of blink::PerformanceEntry.
Owner: panicker@chromium.org
panicker@: Would you mind taking a look? It looks like we sometimes allocate a crazy number of PerformanceEntry objects.

Cc: sunjian@chromium.org
Yes, I'll take a look in the morning.
Any idea about the CL range where the regression was observed?


Cc: n...@fb.com bmau...@fb.com
AFAICT we haven't made recent changes to PerformanceBase::addResourceTiming.
From a quick initial look it appears that the resourcetimingbuffer can be set arbitrarily (upto max size of unsigned) by the user.
So as a first step it might be good to determine whether Facebook is setting this to a very large value OR we are leaking these objects.



Comment 6 by ssid@chromium.org, Jan 26 2017

It's just an observation from my testing. So I can't tell when it started.
Summary: 2MiB increase in PerformanceResourceTiming after 3 days of facebook.com (was: PerformanceResourceTiming causes 2MiB memory regression on renderer)
rewording the title as this is not a regression, but an investigation.
panicker@ are you suggesting that this is WAI if the client actually requested a 2 MB buffer via JS? If so looks like something we should keep track of in memory-infra.

(I agree this is not a regression, but a bug)
Yes, we can definitely fix the implementation and the spec to cap the buffer size.
Would be great to determine if that's the issue that ssid@ is observing though.
Owner: ssid@chromium.org
ssid: can you check #9 ?
Re #9: lemme clarify my position: if this is due to the JS content doing  Performance.setResourceTimingBufferSize(1000) I think all this becomes WAI as this is not different than the content doing: new Array(1000).
The only action in this case would be:
- improving the memory instrumentation code we have to make sure we surface this to avoid reopening a bug like this next time.
- maybe reaching out to FB folks and pointing out that it has a cost.

If this turns out to be a more endemic problem, we can evaluate whether there is something that could be done to reduce the per-event memory footprint of the resource timing buffer itself, or cap it as you say.

Comment 11 by bmau...@fb.com, Jan 26 2017

Part of the problem here is that without setting a large buffer it is difficult to ensure that events are not missed. With performance observer this should eventually become less of an issue. If you guys think this is a large issue in the short term we could explore clearing the buffer more aggressively. I also think it wouldn't be unreasonable to have the platform expire entries after N minutes. 

Comment 12 by ssid@chromium.org, Jan 26 2017

Cc: hajimehoshi@chromium.org tasak@chromium.org
Labels: -Type-Bug -Pri-2 Pri-3 Type-Feature
Owner: keishi@chromium.org
Just verified that the value is set to 100000 by facebook.com. By comment #11, I think the main issue here is to keep around this buffer for days. But it might not be worth fixing this issue and updating the spec. panicker@ would that be an easy fix?

Re-assigning to keishi to verify if we need a dump provider to account for these performance timing objects.
Reducing priority and marking this as feature.
Capping the buffer in the implementation right now (without spec update) would cause an interoperability issue / inconsistency between browsers.
From the spec perspective the answer here is to use PerformanceObserver moving forward.
I can't think of short term fixes other than making developers aware of the cost.


Cc: pfeldman@chromium.org
Makes sense.
+pfeldman
TL;DR a high Performance.setResourceTimingBufferSize() can cause a non-trivial (~2 MiB) use of memory in the renderer. I wonder it would make sense having this surfaced in devtools' memory pane.
Can we make PerformanceResourceTiming listen to MemoryCoordinator so that it can clear the buffer when the system is under high memory pressure?

> I wonder it would make sense having this surfaced in devtools' memory pane.

What's your goal here? We could emit a 'performance violation' into console when it happens.
Just to confirm: Per the spec, is it okay to clear the buffer at any time?

Re #16:
> What's your goal here?
Essentially the TL;DR of this bug is that if developer use a given JS feature (Performance.setResourceTimingBufferSize()) they end up using memory which is *not* acounted by the V8 heap, and hence, by the devtools heap profiler tooling.

But they (JS developers) are directly responsible for it, so maybe that information should be surfaced to them in some way? Not sure what the best way of surfacing it is (or surfacing makes sense at all). 

The spec says:
The user agent may choose to limit how many resources are included as PerformanceResourceTiming objects in the Performance Timeline [PERFORMANCE-TIMELINE-2].
https://w3c.github.io/resource-timing/#dom-performance-setresourcetimingbuffersize

So could we clear m_resourceTimingBuffer when we are under memory pressure?
Cc: panicker@chromium.org
I filed this bug asking for clarification whether we can clear the buffer under pressure: 
https://github.com/w3c/resource-timing/issues/94
Clearing the buffer under high memory pressure definitely sounds reasonable to me.

FWIW, surfacing these types of egregious performance violations to the web developer totally makes sense to me.
Do we have an idea on how wide spread that is? Typical user is not looking at the heap profiler, so I would not put it there. Depending on how systematic that is, we could surface it in different places. For example, if particular framework is doing it without the users's explicit consent, we could yell at the library in console.

If that is a one-off case though, we would place it elsewhere. Still hesitant putting it into Memory. Btw, the API is a footgun it seems, we should totally ignore the given value.

Comment 22 by n...@fb.com, Jan 27 2017

Labels: DevRel-Facebook
My sense is that this particular issue of making massive buffers for Resource Timing is one-off. The explicit recommendation is small buffer sizes. 
Are you asking about the more general question of developers inadvertently causing large memory bloat? That seems worth surfacing somehow.
I don't think we need to do something just for this specific case.

Comment 24 by n...@fb.com, Jan 27 2017

Yeah, this is a one off issue on our end. We're going to follow up and come up with something better here. In general we haven't seen many issues come up because of this, so thanks for the report!
Status: Assigned (was: Untriaged)
Since there is an owner, change status to assigned.
Status: WontFix (was: Assigned)
I don't think there's anything to do here beyond the spec bug that was filed:
https://github.com/w3c/resource-timing/issues/94

Sign in to add a comment