Chromium Code Reviews

Side by Side Diff: Source/platform/heap/ThreadState.cpp

Issue 1174123002: Oilpan: adjust GC policy under memory pressure. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 554 matching lines...)
565 // Heap::markedObjectSize() may be underestimated if any thread has not 565 // Heap::markedObjectSize() may be underestimated if any thread has not
566 // finished completeSweep(). 566 // finished completeSweep().
567 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages(); 567 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages();
568 // Schedule a precise GC if Oilpan has allocated more than 1 MB since 568 // Schedule a precise GC if Oilpan has allocated more than 1 MB since
569 // the last GC and the current memory usage is >50% larger than 569 // the last GC and the current memory usage is >50% larger than
570 // the estimated live memory usage. 570 // the estimated live memory usage.
571 return allocatedObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLi veObjectSize * 3 / 2; 571 return allocatedObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLi veObjectSize * 3 / 2;
572 #endif 572 #endif
573 } 573 }
574 574
575 namespace {
haraken 2015/06/11 04:10:30 Or static. No strong opinion.
576
577 inline bool shouldForceMemoryPressureGC(size_t currentSize, size_t estimatedSize )
haraken 2015/06/11 04:10:30 currentObjectSize, estimatedLiveObjectSize
578 {
579 if (currentSize < 300 * 1024 * 1024)
580 return false;
581
582 // If we're consuming too much memory, trigger a conservative GC
583 // aggressively. This is a safe guard to avoid OOM.
584 return (currentSize >> 10) > (estimatedSize >> 10) * 3 / 2;
haraken 2015/06/11 04:10:30 Add a comment about why we want to shift the size.
sof 2015/06/11 08:45:02 Done.
585 }
586
587 } // namespace
588
575 // TODO(haraken): We should improve the GC heuristics. 589 // TODO(haraken): We should improve the GC heuristics.
576 // These heuristics affect performance significantly. 590 // These heuristics affect performance significantly.
577 bool ThreadState::shouldForceConservativeGC() 591 bool ThreadState::shouldForceConservativeGC()
578 { 592 {
579 if (UNLIKELY(isGCForbidden())) 593 if (UNLIKELY(isGCForbidden()))
580 return false; 594 return false;
581 595
582 // The estimated size is updated when the main thread finishes lazy 596 // The estimated size is updated when the main thread finishes lazy
583 // sweeping. If this thread reaches here before the main thread finishes 597 // sweeping. If this thread reaches here before the main thread finishes
584 // lazy sweeping, the thread will use the estimated size of the last GC. 598 // lazy sweeping, the thread will use the estimated size of the last GC.
585 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); 599 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
586 size_t allocatedObjectSize = Heap::allocatedObjectSize(); 600 size_t allocatedObjectSize = Heap::allocatedObjectSize();
587 // Heap::markedObjectSize() may be underestimated if any thread has not 601 // Heap::markedObjectSize() may be underestimated if any thread has not
588 // finished completeSweep(). 602 // finished completeSweep().
589 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages(); 603 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages();
590 if (currentObjectSize >= 300 * 1024 * 1024) { 604 if (shouldForceMemoryPressureGC(currentObjectSize, estimatedLiveObjectSize))
591 // If we're consuming too much memory, trigger a conservative GC 605 return true;
592 // aggressively. This is a safe guard to avoid OOM.
593 return currentObjectSize > estimatedLiveObjectSize * 3 / 2;
594 }
595 // Schedule a conservative GC if Oilpan has allocated more than 32 MB since 606 // Schedule a conservative GC if Oilpan has allocated more than 32 MB since
596 // the last GC and the current memory usage is >400% larger than 607 // the last GC and the current memory usage is >400% larger than
597 // the estimated live memory usage. 608 // the estimated live memory usage.
598 // TODO(haraken): 400% is too large. Lower the heap growing factor. 609 // TODO(haraken): 400% is too large. Lower the heap growing factor.
599 return allocatedObjectSize >= 32 * 1024 * 1024 && currentObjectSize > 5 * es timatedLiveObjectSize; 610 return allocatedObjectSize >= 32 * 1024 * 1024 && currentObjectSize > 5 * es timatedLiveObjectSize;
600 } 611 }
601 612
602 void ThreadState::scheduleGCIfNeeded() 613 void ThreadState::scheduleGCIfNeeded()
603 { 614 {
604 checkThread(); 615 checkThread();
(...skipping 180 matching lines...)
785 796
786 ThreadState::GCState ThreadState::gcState() const 797 ThreadState::GCState ThreadState::gcState() const
787 { 798 {
788 return m_gcState; 799 return m_gcState;
789 } 800 }
790 801
791 void ThreadState::didV8GC() 802 void ThreadState::didV8GC()
792 { 803 {
793 checkThread(); 804 checkThread();
794 if (isMainThread()) { 805 if (isMainThread()) {
806 size_t currentObjectSize = Heap::allocatedObjectSize() + Heap::markedObj ectSize() + WTF::Partitions::totalSizeOfCommittedPages();
haraken 2015/06/11 04:10:31 Or you can do: if (shouldForceMemoryPressureGC(
807 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize();
808 if (shouldForceMemoryPressureGC(currentObjectSize, estimatedLiveObjectSi ze)) {
809 // Under memory pressure, force a conservative GC.
810 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::Cons ervativeGC);
811 return;
812 }
795 // Lower the estimated live object size because the V8 major GC is 813 // Lower the estimated live object size because the V8 major GC is
796 // expected to have collected a lot of DOM wrappers and dropped 814 // expected to have collected a lot of DOM wrappers and dropped
797 // references to their DOM objects. 815 // references to their DOM objects.
798 Heap::setEstimatedLiveObjectSize(Heap::estimatedLiveObjectSize() / 2); 816 Heap::setEstimatedLiveObjectSize(Heap::estimatedLiveObjectSize() / 2);
haraken 2015/06/11 04:10:31 I think we should do this first. Maybe a better f
sof 2015/06/11 08:45:02 Nice. I think that makes good sense, shifting this
799 } 817 }
800 } 818 }
801 819
802 void ThreadState::runScheduledGC(StackState stackState) 820 void ThreadState::runScheduledGC(StackState stackState)
803 { 821 {
804 checkThread(); 822 checkThread();
805 if (stackState != NoHeapPointersOnStack) 823 if (stackState != NoHeapPointersOnStack)
806 return; 824 return;
807 825
808 // If a safe point is entered while initiating a GC, we clearly do 826 // If a safe point is entered while initiating a GC, we clearly do
(...skipping 568 matching lines...)
1377 json->beginArray(it->key.ascii().data()); 1395 json->beginArray(it->key.ascii().data());
1378 for (size_t age = 0; age <= maxHeapObjectAge; ++age) 1396 for (size_t age = 0; age <= maxHeapObjectAge; ++age)
1379 json->pushInteger(it->value.ages[age]); 1397 json->pushInteger(it->value.ages[age]);
1380 json->endArray(); 1398 json->endArray();
1381 } 1399 }
1382 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release()); 1400 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release());
1383 } 1401 }
1384 #endif 1402 #endif
1385 1403
1386 } // namespace blink 1404 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine