Chromium Code Reviews| OLD | NEW |
|---|---|
| 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...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 |
| OLD | NEW |