From 68d8df67b91778854951a2d891d1e012227b868e Mon Sep 17 00:00:00 2001 From: "msaboff@apple.com" Date: Mon, 2 Apr 2012 18:13:37 +0000 Subject: [PATCH] WebKit should throttle memory pressure notifications in proportion to handler time https://bugs.webkit.org/show_bug.cgi?id=82674 Reviewed by Geoffrey Garen. Changed the MemoryPressureHandler hold off timer to start timing after respondToMemoryPressure runs. The delay time is now 20 times longer than the time it took for respondToMemoryPressure to run with a minimum of 5 seconds. This throttles the response to low memory events in the extreme case where we are spending most of our time paging / swapping. This is a Mac only change. No additional tests. This passes existing test and was verified using manual tests on a small memory system with many websites open. * platform/mac/MemoryPressureHandlerMac.mm: (WebCore): (WebCore::MemoryPressureHandler::holdOff): (WebCore::MemoryPressureHandler::respondToMemoryPressure): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@112910 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 22 +++++++++++++++ .../platform/mac/MemoryPressureHandlerMac.mm | 31 +++++++++++++++++----- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 0aa770a..cef5e6e 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,25 @@ +2012-04-02 Michael Saboff + + WebKit should throttle memory pressure notifications in proportion to handler time + https://bugs.webkit.org/show_bug.cgi?id=82674 + + Reviewed by Geoffrey Garen. + + Changed the MemoryPressureHandler hold off timer to start timing after + respondToMemoryPressure runs. The delay time is now 20 times longer than the + time it took for respondToMemoryPressure to run with a minimum of 5 seconds. + This throttles the response to low memory events in the extreme case where + we are spending most of our time paging / swapping. + This is a Mac only change. + + No additional tests. This passes existing test and was verified using + manual tests on a small memory system with many websites open. + + * platform/mac/MemoryPressureHandlerMac.mm: + (WebCore): + (WebCore::MemoryPressureHandler::holdOff): + (WebCore::MemoryPressureHandler::respondToMemoryPressure): + 2012-04-02 Sheriff Bot Unreviewed, rolling out r112163. diff --git a/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm b/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm index 1727bac..2247546 100644 --- a/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm +++ b/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm @@ -30,6 +30,7 @@ #import #import #import +#import #import #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !PLATFORM(IOS) @@ -46,10 +47,14 @@ static dispatch_source_t _cache_event_source = 0; static dispatch_source_t _timer_event_source = 0; static int _notifyToken; -// Disable memory event reception for 5 seconds after receiving an event. -// This value seems reasonable and testing verifies that it throttles frequent +// Disable memory event reception for a minimum of s_minimumHoldOffTime +// seconds after receiving an event. Don't let events fire any sooner than +// s_holdOffMultiplier times the last cleanup processing time. Effectively +// this is 1 / s_holdOffMultiplier percent of the time. +// These value seems reasonable and testing verifies that it throttles frequent // low memory events, greatly reducing CPU usage. -static const time_t s_secondsBetweenMemoryCleanup = 5; +static const time_t s_minimumHoldOffTime = 5; +static const time_t s_holdOffMultiplier = 20; void MemoryPressureHandler::install() { @@ -93,13 +98,11 @@ void MemoryPressureHandler::uninstall() void MemoryPressureHandler::holdOff(unsigned seconds) { - uninstall(); - dispatch_async(dispatch_get_main_queue(), ^{ _timer_event_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); if (_timer_event_source) { dispatch_set_context(_timer_event_source, this); - dispatch_source_set_timer(_timer_event_source, dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 1 * s_secondsBetweenMemoryCleanup); + dispatch_source_set_timer(_timer_event_source, dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 1 * s_minimumHoldOffTime); dispatch_source_set_event_handler(_timer_event_source, ^{ dispatch_source_cancel(_timer_event_source); dispatch_release(_timer_event_source); @@ -113,9 +116,23 @@ void MemoryPressureHandler::holdOff(unsigned seconds) void MemoryPressureHandler::respondToMemoryPressure() { - holdOff(s_secondsBetweenMemoryCleanup); + double startTime, endTime; + unsigned holdOffTime; + + uninstall(); + + startTime = monotonicallyIncreasingTime(); releaseMemory(false); + + endTime = monotonicallyIncreasingTime(); + + holdOffTime = (unsigned)((endTime - startTime) * (double)s_holdOffMultiplier); + + if (holdOffTime < s_minimumHoldOffTime) + holdOffTime = s_minimumHoldOffTime; + + holdOff(holdOffTime); } #endif // !PLATFORM(IOS) -- 2.7.4