| Index: Source/platform/heap/ThreadState.cpp
|
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
|
| index 931f90e60524d9b4d641d7c38e2a854594ae0efe..ce2fc79e21c42f39a9d22b65e0e4a545ba34586f 100644
|
| --- a/Source/platform/heap/ThreadState.cpp
|
| +++ b/Source/platform/heap/ThreadState.cpp
|
| @@ -529,6 +529,19 @@ Mutex& ThreadState::globalRootsMutex()
|
| return mutex;
|
| }
|
|
|
| +bool ThreadState::shouldForceMemoryPressureGC()
|
| +{
|
| + // Avoid potential overflow by truncating to Kb.
|
| + size_t currentObjectSizeKb = (Heap::allocatedObjectSize() + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10;
|
| + if (currentObjectSizeKb < 300 * 1024)
|
| + return false;
|
| +
|
| + size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
|
| + // If we're consuming too much memory, trigger a conservative GC
|
| + // aggressively. This is a safe guard to avoid OOM.
|
| + return currentObjectSizeKb > (estimatedLiveObjectSizeKb * 3) / 2;
|
| +}
|
| +
|
| // TODO(haraken): We should improve the GC heuristics.
|
| // These heuristics affect performance significantly.
|
| bool ThreadState::shouldScheduleIdleGC()
|
| @@ -536,18 +549,19 @@ bool ThreadState::shouldScheduleIdleGC()
|
| if (gcState() != NoGCScheduled)
|
| return false;
|
| #if ENABLE(IDLE_GC)
|
| + // Avoid potential overflow by truncating to Kb.
|
| + size_t allocatedObjectSizeKb = Heap::allocatedObjectSize() >> 10;
|
| // The estimated size is updated when the main thread finishes lazy
|
| // sweeping. If this thread reaches here before the main thread finishes
|
| // lazy sweeping, the thread will use the estimated size of the last GC.
|
| - size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
|
| - size_t allocatedObjectSize = Heap::allocatedObjectSize();
|
| + size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
|
| // Heap::markedObjectSize() may be underestimated if any thread has not
|
| // finished completeSweep().
|
| - size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages();
|
| + size_t currentObjectSizeKb = allocatedObjectSizeKb + ((Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10);
|
| // Schedule an idle GC if Oilpan has allocated more than 1 MB since
|
| // the last GC and the current memory usage is >50% larger than
|
| // the estimated live memory usage.
|
| - return allocatedObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLiveObjectSize * 3 / 2;
|
| + return allocatedObjectSizeKb >= 1024 && currentObjectSizeKb > (estimatedLiveObjectSizeKb * 3) / 2;
|
| #else
|
| return false;
|
| #endif
|
| @@ -562,18 +576,19 @@ bool ThreadState::shouldSchedulePreciseGC()
|
| #if ENABLE(IDLE_GC)
|
| return false;
|
| #else
|
| + // Avoid potential overflow by truncating to Kb.
|
| + size_t allocatedObjectSizeKb = Heap::allocatedObjectSize() >> 10;
|
| // The estimated size is updated when the main thread finishes lazy
|
| // sweeping. If this thread reaches here before the main thread finishes
|
| // lazy sweeping, the thread will use the estimated size of the last GC.
|
| - size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
|
| - size_t allocatedObjectSize = Heap::allocatedObjectSize();
|
| + size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
|
| // Heap::markedObjectSize() may be underestimated if any thread has not
|
| // finished completeSweep().
|
| - size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages();
|
| + size_t currentObjectSizeKb = allocatedObjectSizeKb + ((Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10);
|
| // Schedule a precise GC if Oilpan has allocated more than 1 MB since
|
| // the last GC and the current memory usage is >50% larger than
|
| // the estimated live memory usage.
|
| - return allocatedObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLiveObjectSize * 3 / 2;
|
| + return allocatedObjectSizeKb >= 1024 && currentObjectSizeKb > (estimatedLiveObjectSizeKb * 3) / 2;
|
| #endif
|
| }
|
|
|
| @@ -584,24 +599,23 @@ bool ThreadState::shouldForceConservativeGC()
|
| if (UNLIKELY(isGCForbidden()))
|
| return false;
|
|
|
| + if (shouldForceMemoryPressureGC())
|
| + return true;
|
| +
|
| + // Avoid potential overflow by truncating to Kb.
|
| + size_t allocatedObjectSizeKb = Heap::allocatedObjectSize() >> 10;
|
| // The estimated size is updated when the main thread finishes lazy
|
| // sweeping. If this thread reaches here before the main thread finishes
|
| // lazy sweeping, the thread will use the estimated size of the last GC.
|
| - size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
|
| - size_t allocatedObjectSize = Heap::allocatedObjectSize();
|
| + size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
|
| // Heap::markedObjectSize() may be underestimated if any thread has not
|
| // finished completeSweep().
|
| - size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages();
|
| - if (currentObjectSize >= 300 * 1024 * 1024) {
|
| - // If we're consuming too much memory, trigger a conservative GC
|
| - // aggressively. This is a safe guard to avoid OOM.
|
| - return currentObjectSize > estimatedLiveObjectSize * 3 / 2;
|
| - }
|
| + size_t currentObjectSizeKb = allocatedObjectSizeKb + ((Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10);
|
| // Schedule a conservative GC if Oilpan has allocated more than 32 MB since
|
| // the last GC and the current memory usage is >400% larger than
|
| // the estimated live memory usage.
|
| // TODO(haraken): 400% is too large. Lower the heap growing factor.
|
| - return allocatedObjectSize >= 32 * 1024 * 1024 && currentObjectSize > 5 * estimatedLiveObjectSize;
|
| + return allocatedObjectSizeKb >= 32 * 1024 && currentObjectSizeKb > 5 * estimatedLiveObjectSizeKb;
|
| }
|
|
|
| void ThreadState::scheduleGCIfNeeded()
|
| @@ -802,7 +816,7 @@ ThreadState::GCState ThreadState::gcState() const
|
| return m_gcState;
|
| }
|
|
|
| -void ThreadState::didV8GC()
|
| +void ThreadState::didV8MajorGC()
|
| {
|
| checkThread();
|
| if (isMainThread()) {
|
| @@ -810,6 +824,12 @@ void ThreadState::didV8GC()
|
| // expected to have collected a lot of DOM wrappers and dropped
|
| // references to their DOM objects.
|
| Heap::setEstimatedLiveObjectSize(Heap::estimatedLiveObjectSize() / 2);
|
| +
|
| + if (shouldForceMemoryPressureGC()) {
|
| + // Under memory pressure, force a conservative GC.
|
| + Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::ConservativeGC);
|
| + return;
|
| + }
|
| }
|
| }
|
|
|
|
|