Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

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

Issue 1190513006: Oilpan: adjust GC policy under memory pressure (only.) (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. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | 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 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 AtomicallyInitializedStaticReference(PersistentAnchor, anchor, new Persisten tAnchor); 522 AtomicallyInitializedStaticReference(PersistentAnchor, anchor, new Persisten tAnchor);
523 return anchor; 523 return anchor;
524 } 524 }
525 525
526 Mutex& ThreadState::globalRootsMutex() 526 Mutex& ThreadState::globalRootsMutex()
527 { 527 {
528 AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex); 528 AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex);
529 return mutex; 529 return mutex;
530 } 530 }
531 531
532 bool ThreadState::shouldForceMemoryPressureGC()
533 {
534 // Avoid potential overflow by truncating to Kb.
535 size_t currentObjectSizeKb = (Heap::allocatedObjectSize() + Heap::markedObje ctSize() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10;
536 if (currentObjectSizeKb < 300 * 1024)
537 return false;
538
539 size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
540 // If we're consuming too much memory, trigger a conservative GC
541 // aggressively. This is a safe guard to avoid OOM.
542 return currentObjectSizeKb > (estimatedLiveObjectSizeKb * 3) / 2;
543 }
544
532 // TODO(haraken): We should improve the GC heuristics. 545 // TODO(haraken): We should improve the GC heuristics.
533 // These heuristics affect performance significantly. 546 // These heuristics affect performance significantly.
534 bool ThreadState::shouldScheduleIdleGC() 547 bool ThreadState::shouldScheduleIdleGC()
535 { 548 {
536 if (gcState() != NoGCScheduled) 549 if (gcState() != NoGCScheduled)
537 return false; 550 return false;
538 #if ENABLE(IDLE_GC) 551 #if ENABLE(IDLE_GC)
552 // Avoid potential overflow by truncating to Kb.
553 size_t allocatedObjectSizeKb = Heap::allocatedObjectSize() >> 10;
539 // The estimated size is updated when the main thread finishes lazy 554 // The estimated size is updated when the main thread finishes lazy
540 // sweeping. If this thread reaches here before the main thread finishes 555 // sweeping. If this thread reaches here before the main thread finishes
541 // lazy sweeping, the thread will use the estimated size of the last GC. 556 // lazy sweeping, the thread will use the estimated size of the last GC.
542 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); 557 size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
543 size_t allocatedObjectSize = Heap::allocatedObjectSize();
544 // Heap::markedObjectSize() may be underestimated if any thread has not 558 // Heap::markedObjectSize() may be underestimated if any thread has not
545 // finished completeSweep(). 559 // finished completeSweep().
546 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages(); 560 size_t currentObjectSizeKb = allocatedObjectSizeKb + ((Heap::markedObjectSiz e() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10);
547 // Schedule an idle GC if Oilpan has allocated more than 1 MB since 561 // Schedule an idle GC if Oilpan has allocated more than 1 MB since
548 // the last GC and the current memory usage is >50% larger than 562 // the last GC and the current memory usage is >50% larger than
549 // the estimated live memory usage. 563 // the estimated live memory usage.
550 return allocatedObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLi veObjectSize * 3 / 2; 564 return allocatedObjectSizeKb >= 1024 && currentObjectSizeKb > (estimatedLive ObjectSizeKb * 3) / 2;
551 #else 565 #else
552 return false; 566 return false;
553 #endif 567 #endif
554 } 568 }
555 569
556 // TODO(haraken): We should improve the GC heuristics. 570 // TODO(haraken): We should improve the GC heuristics.
557 // These heuristics affect performance significantly. 571 // These heuristics affect performance significantly.
558 bool ThreadState::shouldSchedulePreciseGC() 572 bool ThreadState::shouldSchedulePreciseGC()
559 { 573 {
560 if (gcState() != NoGCScheduled) 574 if (gcState() != NoGCScheduled)
561 return false; 575 return false;
562 #if ENABLE(IDLE_GC) 576 #if ENABLE(IDLE_GC)
563 return false; 577 return false;
564 #else 578 #else
579 // Avoid potential overflow by truncating to Kb.
580 size_t allocatedObjectSizeKb = Heap::allocatedObjectSize() >> 10;
565 // The estimated size is updated when the main thread finishes lazy 581 // The estimated size is updated when the main thread finishes lazy
566 // sweeping. If this thread reaches here before the main thread finishes 582 // sweeping. If this thread reaches here before the main thread finishes
567 // lazy sweeping, the thread will use the estimated size of the last GC. 583 // lazy sweeping, the thread will use the estimated size of the last GC.
568 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); 584 size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
569 size_t allocatedObjectSize = Heap::allocatedObjectSize();
570 // Heap::markedObjectSize() may be underestimated if any thread has not 585 // Heap::markedObjectSize() may be underestimated if any thread has not
571 // finished completeSweep(). 586 // finished completeSweep().
572 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages(); 587 size_t currentObjectSizeKb = allocatedObjectSizeKb + ((Heap::markedObjectSiz e() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10);
573 // Schedule a precise GC if Oilpan has allocated more than 1 MB since 588 // Schedule a precise GC if Oilpan has allocated more than 1 MB since
574 // the last GC and the current memory usage is >50% larger than 589 // the last GC and the current memory usage is >50% larger than
575 // the estimated live memory usage. 590 // the estimated live memory usage.
576 return allocatedObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLi veObjectSize * 3 / 2; 591 return allocatedObjectSizeKb >= 1024 && currentObjectSizeKb > (estimatedLive ObjectSizeKb * 3) / 2;
577 #endif 592 #endif
578 } 593 }
579 594
580 // TODO(haraken): We should improve the GC heuristics. 595 // TODO(haraken): We should improve the GC heuristics.
581 // These heuristics affect performance significantly. 596 // These heuristics affect performance significantly.
582 bool ThreadState::shouldForceConservativeGC() 597 bool ThreadState::shouldForceConservativeGC()
583 { 598 {
584 if (UNLIKELY(isGCForbidden())) 599 if (UNLIKELY(isGCForbidden()))
585 return false; 600 return false;
586 601
602 if (shouldForceMemoryPressureGC())
603 return true;
604
605 // Avoid potential overflow by truncating to Kb.
606 size_t allocatedObjectSizeKb = Heap::allocatedObjectSize() >> 10;
587 // The estimated size is updated when the main thread finishes lazy 607 // The estimated size is updated when the main thread finishes lazy
588 // sweeping. If this thread reaches here before the main thread finishes 608 // sweeping. If this thread reaches here before the main thread finishes
589 // lazy sweeping, the thread will use the estimated size of the last GC. 609 // lazy sweeping, the thread will use the estimated size of the last GC.
590 size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); 610 size_t estimatedLiveObjectSizeKb = Heap::estimatedLiveObjectSize() >> 10;
591 size_t allocatedObjectSize = Heap::allocatedObjectSize();
592 // Heap::markedObjectSize() may be underestimated if any thread has not 611 // Heap::markedObjectSize() may be underestimated if any thread has not
593 // finished completeSweep(). 612 // finished completeSweep().
594 size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages(); 613 size_t currentObjectSizeKb = allocatedObjectSizeKb + ((Heap::markedObjectSiz e() + WTF::Partitions::totalSizeOfCommittedPages()) >> 10);
595 if (currentObjectSize >= 300 * 1024 * 1024) {
596 // If we're consuming too much memory, trigger a conservative GC
597 // aggressively. This is a safe guard to avoid OOM.
598 return currentObjectSize > estimatedLiveObjectSize * 3 / 2;
599 }
600 // Schedule a conservative GC if Oilpan has allocated more than 32 MB since 614 // Schedule a conservative GC if Oilpan has allocated more than 32 MB since
601 // the last GC and the current memory usage is >400% larger than 615 // the last GC and the current memory usage is >400% larger than
602 // the estimated live memory usage. 616 // the estimated live memory usage.
603 // TODO(haraken): 400% is too large. Lower the heap growing factor. 617 // TODO(haraken): 400% is too large. Lower the heap growing factor.
604 return allocatedObjectSize >= 32 * 1024 * 1024 && currentObjectSize > 5 * es timatedLiveObjectSize; 618 return allocatedObjectSizeKb >= 32 * 1024 && currentObjectSizeKb > 5 * estim atedLiveObjectSizeKb;
605 } 619 }
606 620
607 void ThreadState::scheduleGCIfNeeded() 621 void ThreadState::scheduleGCIfNeeded()
608 { 622 {
609 checkThread(); 623 checkThread();
610 // Allocation is allowed during sweeping, but those allocations should not 624 // Allocation is allowed during sweeping, but those allocations should not
611 // trigger nested GCs. 625 // trigger nested GCs.
612 if (isSweepingInProgress()) 626 if (isSweepingInProgress())
613 return; 627 return;
614 ASSERT(!sweepForbidden()); 628 ASSERT(!sweepForbidden());
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 m_gcState = gcState; 809 m_gcState = gcState;
796 } 810 }
797 811
798 #undef VERIFY_STATE_TRANSITION 812 #undef VERIFY_STATE_TRANSITION
799 813
800 ThreadState::GCState ThreadState::gcState() const 814 ThreadState::GCState ThreadState::gcState() const
801 { 815 {
802 return m_gcState; 816 return m_gcState;
803 } 817 }
804 818
805 void ThreadState::didV8GC() 819 void ThreadState::didV8MajorGC()
806 { 820 {
807 checkThread(); 821 checkThread();
808 if (isMainThread()) { 822 if (isMainThread()) {
809 // Lower the estimated live object size because the V8 major GC is 823 // Lower the estimated live object size because the V8 major GC is
810 // expected to have collected a lot of DOM wrappers and dropped 824 // expected to have collected a lot of DOM wrappers and dropped
811 // references to their DOM objects. 825 // references to their DOM objects.
812 Heap::setEstimatedLiveObjectSize(Heap::estimatedLiveObjectSize() / 2); 826 Heap::setEstimatedLiveObjectSize(Heap::estimatedLiveObjectSize() / 2);
827
828 #if 0
829 if (shouldForceMemoryPressureGC()) {
830 // Under memory pressure, force a conservative GC.
831 Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::Cons ervativeGC);
832 return;
833 }
haraken 2015/06/16 16:21:27 Actually I don't fully understand an issue of call
sof 2015/06/16 16:27:31 Oops, #if 0 - will undo that, ofc. It triggering
haraken 2015/06/16 16:36:44 I'm OK with landing this CL, but that sounds like
834 #endif
813 } 835 }
814 } 836 }
815 837
816 void ThreadState::runScheduledGC(StackState stackState) 838 void ThreadState::runScheduledGC(StackState stackState)
817 { 839 {
818 checkThread(); 840 checkThread();
819 if (stackState != NoHeapPointersOnStack) 841 if (stackState != NoHeapPointersOnStack)
820 return; 842 return;
821 843
822 // If a safe point is entered while initiating a GC, we clearly do 844 // If a safe point is entered while initiating a GC, we clearly do
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 json->beginArray(it->key.ascii().data()); 1449 json->beginArray(it->key.ascii().data());
1428 for (size_t age = 0; age <= maxHeapObjectAge; ++age) 1450 for (size_t age = 0; age <= maxHeapObjectAge; ++age)
1429 json->pushInteger(it->value.ages[age]); 1451 json->pushInteger(it->value.ages[age]);
1430 json->endArray(); 1452 json->endArray();
1431 } 1453 }
1432 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release()); 1454 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s tatsName, this, json.release());
1433 } 1455 }
1434 #endif 1456 #endif
1435 1457
1436 } // namespace blink 1458 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698