SlideShare a Scribd company logo
1 of 15
Download to read offline
Semi-Space Garbage Collector
Haifeng Li
2014-6-10
Outline
• Current Garbage Collectors in ART
• Heap in VM Process
• Semi-Space Collector
• Optimization
• Whole Heap Collection
• Other Semi-Space Collector
– ZygoteCompactingCollector
Current Garbage Collectors in ART
• Mark-Sweep Collector
– Concurrent Sticky/Partial/Full (CMS)
– Non-Concurrent Sticky/Partial/Full (MS)
• Semi-Space Collector
– Generational Semi-Space
– Semi-Space(GSS+ Partial Mark-Sweep)
• Concurrent-Copying
– Under developing…
Heap in VM Process
Image Space
Zygote
Space
Main Space
Non Moving
Space
Temp_space
Bump pointer
Space
60+MB 10+MB 64MB
128MB 128MB
Large Object Space
Semi-Space Collector: Compacting
• It is for Bump pointer Space
• After one SS,
• So, it’s also named Compacting collector.
• For mark sweep, it is treated as normal space, like main space
Semi-Space Collector: Promoted
Semi-Space Collector
• All phases in GC should suspend all mutators.
64 class SemiSpace : public GarbageCollector {
…
72 virtual bool IsConcurrent() const {
73 return false;
74 }
75 virtual void MarkingPhase() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
76 virtual void ReclaimPhase() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
77 virtual void FinishPhase() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
…
}
Semi-Space Collector: Mark
• If object A is in from_space
– If two most significant bits of object A->monitor is
not 3
• Copy object A to to_space or promoted_space A’
• Update object A->monitor.
• Push New object A’ to mark_stack.
• Else if object is not in Immune_region
– Mark action same as mark_sweep action.
* |33|22222222221111|1111110000000000|
* |10|98765432109876|5432109876543210|
* |11| object’s new location address >>2 |
Semi-Space Collector: Reclaim
• Sweep
• BumpPointerSpace::Clear
– madvise(Begin(), Limit() - Begin(), MADV_DONTNEED)
madvise:: MADV_DONTNEED
Subsequent accesses of pages in this range will succeed, but will result either in
reloading of the memory contents from the underlying mapped file or zero-fill-
on-demand pages for mappings without an underlying file.
Optimization
• Though just collector garbage of bump pointer
space, the non moving space and main space
mast be scanned and marked. This is
inefficient.
• RememberedSet is involved by Hiroshi
Yamauchi. It is same to ModUnionTable. It
trace the reference from non-moving
space/main space to bump pointer space.
Process Cards
void Heap::ProcessCards(TimingLogger& timings, bool use_rem_sets) {
// Clear cards and keep track of cards cleared in the mod-union table.
for (const auto& space : continuous_spaces_) {
accounting::ModUnionTable* table = FindModUnionTableFromSpace(space);
+ accounting::RememberedSet* rem_set = FindRememberedSetFromSpace(space);
if (table != nullptr) {
const char* name = space->IsZygoteSpace() ? "ZygoteModUnionClearCards" :
"ImageModUnionClearCards";
TimingLogger::ScopedSplit split(name, &timings);
table->ClearCards();
+ } else if (use_rem_sets && rem_set != nullptr) {
+ DCHECK(collector::SemiSpace::kUseRememberedSet && collector_type_ == kCollectorTypeGSS)
+ << static_cast<int>(collector_type_);
+ TimingLogger::ScopedSplit split("AllocSpaceRemSetClearCards", &timings);
+ rem_set->ClearCards();
} else if (space->GetType() != space::kSpaceTypeBumpPointerSpace) {
TimingLogger::ScopedSplit split("AllocSpaceClearCards", &timings);
// No mod union table for the AllocSpace. Age the cards so that the GC knows that these cards
// were dirty before the GC started.
// TODO: Need to use atomic for the case where aged(cleaning thread) -> dirty(other thread)
// -> clean(cleaning thread).
// The races are we either end up with: Aged card, unaged card. Since we have the checkpoint
// roots and then we scan / update mod union tables after. We will always scan either card.
// If we end up with the non aged card, we scan it it in the pause.
card_table_->ModifyCardsAtomic(space->Begin(), space->End(), AgeCardVisitor(), VoidFunctor());
}
}
}
Update RememberedSet
void RememberedSet::UpdateAndMarkReferences(MarkObjectCallback* callback,
space::ContinuousSpace* target_space, void* arg) {
CardTable* card_table = heap_->GetCardTable();
bool contains_reference_to_target_space = false;
RememberedSetObjectVisitor obj_visitor(callback, target_space,
&contains_reference_to_target_space, arg);
SpaceBitmap* bitmap = space_->GetLiveBitmap();
CardSet remove_card_set;
for (byte* const card_addr : dirty_cards_) {
contains_reference_to_target_space = false;
uintptr_t start = reinterpret_cast<uintptr_t>(card_table->AddrFromCard(card_addr));
DCHECK(space_->HasAddress(reinterpret_cast<mirror::Object*>(start)));
bitmap->VisitMarkedRange(start, start + CardTable::kCardSize, obj_visitor);
if (!contains_reference_to_target_space) {
// It was in the dirty card set, but it didn't actually contain
// a reference to the target space. So, remove it from the dirty
// card set so we won't have to scan it again (unless it gets
// dirty again.)
remove_card_set.insert(card_addr);
}
}
// Remove the cards that didn't contain a reference to the target
// space from the dirty card set.
for (byte* const card_addr : remove_card_set) {
DCHECK(dirty_cards_.find(card_addr) != dirty_cards_.end());
dirty_cards_.erase(card_addr);
}
}
GSS and Whole Heap Collection
• If promotion bytes or large object bytes
allocated exceeds threshold. GSS will do
partial Mark Sweep + Semi-Space collector on
whole heap.
ZygoteCompactingCollector
• When
– When Zygote fork the first process.
• How
1627 ZygoteCompactingCollector zygote_collector(this);
1628 zygote_collector.BuildBins(non_moving_space_);
1629 // Create a new bump pointer space which we will compact into.
1630 space::BumpPointerSpace target_space("zygote bump space",
non_moving_space_->End(), non_moving_space_->Limit());
1633 // Compact the bump pointer space to a new zygote bump pointer space.
1635 zygote_collector.SetFromSpace(bump_pointer_space_);
1636 zygote_collector.SetToSpace(&target_space);
1637 zygote_collector.Run(kGcCauseCollectorTransition, false);
Backup
703 BoundedFifoPowerOfTwo<Object*, kFifoSize> prefetch_fifo;
705 for (;;) {
706 Object* obj = NULL;
708 while (!mark_stack_->IsEmpty() && prefetch_fifo.size() < kFifoSize) {
709 Object * obj = mark_stack_->PopBack();
710 DCHECK(obj != NULL);
711 __builtin_prefetch(obj);
712 prefetch_fifo.push_back(obj);
713 }
714 if (prefetch_fifo.empty()) {
715 break;
716 }
717 obj = prefetch_fifo.front();
718 prefetch_fifo.pop_front();
737 ScanObject(obj);
738 }
740 }

More Related Content

Viewers also liked (6)

Understanding Monitor in Dalvik
Understanding Monitor in DalvikUnderstanding Monitor in Dalvik
Understanding Monitor in Dalvik
 
Understanding DLmalloc
Understanding DLmallocUnderstanding DLmalloc
Understanding DLmalloc
 
Understanding binder in android
Understanding binder in androidUnderstanding binder in android
Understanding binder in android
 
Process Scheduler and Balancer in Linux Kernel
Process Scheduler and Balancer in Linux KernelProcess Scheduler and Balancer in Linux Kernel
Process Scheduler and Balancer in Linux Kernel
 
AARCH64 VMSA Under Linux Kernel
AARCH64 VMSA Under Linux KernelAARCH64 VMSA Under Linux Kernel
AARCH64 VMSA Under Linux Kernel
 
Understanding SLAB in Linux Kernel
Understanding SLAB in Linux KernelUnderstanding SLAB in Linux Kernel
Understanding SLAB in Linux Kernel
 

Similar to Understanding Semi-Space Garbage Collector in ART

Writing a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdfWriting a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdf
RomanKhavronenko
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
Miller Lee
 
Assignment of SOS operating systemThe file lmemman.c has one incom.pdf
Assignment of SOS operating systemThe file lmemman.c has one incom.pdfAssignment of SOS operating systemThe file lmemman.c has one incom.pdf
Assignment of SOS operating systemThe file lmemman.c has one incom.pdf
sktambifortune
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
Teddy Hsiung
 
Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...
Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...
Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...
Accumulo Summit
 
Memory Optimization
Memory OptimizationMemory Optimization
Memory Optimization
guest3eed30
 
Memory Optimization
Memory OptimizationMemory Optimization
Memory Optimization
Wei Lin
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
Moriyoshi Koizumi
 

Similar to Understanding Semi-Space Garbage Collector in ART (20)

Writing a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdfWriting a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdf
 
Garbage collection in JVM
Garbage collection in JVMGarbage collection in JVM
Garbage collection in JVM
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
 
GC in Ruby. RubyC, Kiev, 2014.
GC in Ruby. RubyC, Kiev, 2014.GC in Ruby. RubyC, Kiev, 2014.
GC in Ruby. RubyC, Kiev, 2014.
 
Introduction to c part -3
Introduction to c   part -3Introduction to c   part -3
Introduction to c part -3
 
Assignment of SOS operating systemThe file lmemman.c has one incom.pdf
Assignment of SOS operating systemThe file lmemman.c has one incom.pdfAssignment of SOS operating systemThe file lmemman.c has one incom.pdf
Assignment of SOS operating systemThe file lmemman.c has one incom.pdf
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
 
Linux kernel memory allocators
Linux kernel memory allocatorsLinux kernel memory allocators
Linux kernel memory allocators
 
Memory
MemoryMemory
Memory
 
C++ amp on linux
C++ amp on linuxC++ amp on linux
C++ amp on linux
 
2011.02.18 marco parenzan - modelli di programmazione per le gpu
2011.02.18   marco parenzan - modelli di programmazione per le gpu2011.02.18   marco parenzan - modelli di programmazione per le gpu
2011.02.18 marco parenzan - modelli di programmazione per le gpu
 
Happy To Use SIMD
Happy To Use SIMDHappy To Use SIMD
Happy To Use SIMD
 
Scope Stack Allocation
Scope Stack AllocationScope Stack Allocation
Scope Stack Allocation
 
Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...
Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...
Accumulo Summit 2016: Introducing Accumulo Collections: A Practical Accumulo ...
 
(5) cpp dynamic memory_arrays_and_c-strings
(5) cpp dynamic memory_arrays_and_c-strings(5) cpp dynamic memory_arrays_and_c-strings
(5) cpp dynamic memory_arrays_and_c-strings
 
Memory Optimization
Memory OptimizationMemory Optimization
Memory Optimization
 
Memory Optimization
Memory OptimizationMemory Optimization
Memory Optimization
 
memory_mapping.ppt
memory_mapping.pptmemory_mapping.ppt
memory_mapping.ppt
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
 
MongoDB
MongoDBMongoDB
MongoDB
 

Recently uploaded

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Cara Menggugurkan Kandungan 087776558899
 

Recently uploaded (6)

Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
 
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 

Understanding Semi-Space Garbage Collector in ART

  • 2. Outline • Current Garbage Collectors in ART • Heap in VM Process • Semi-Space Collector • Optimization • Whole Heap Collection • Other Semi-Space Collector – ZygoteCompactingCollector
  • 3. Current Garbage Collectors in ART • Mark-Sweep Collector – Concurrent Sticky/Partial/Full (CMS) – Non-Concurrent Sticky/Partial/Full (MS) • Semi-Space Collector – Generational Semi-Space – Semi-Space(GSS+ Partial Mark-Sweep) • Concurrent-Copying – Under developing…
  • 4. Heap in VM Process Image Space Zygote Space Main Space Non Moving Space Temp_space Bump pointer Space 60+MB 10+MB 64MB 128MB 128MB Large Object Space
  • 5. Semi-Space Collector: Compacting • It is for Bump pointer Space • After one SS, • So, it’s also named Compacting collector. • For mark sweep, it is treated as normal space, like main space
  • 7. Semi-Space Collector • All phases in GC should suspend all mutators. 64 class SemiSpace : public GarbageCollector { … 72 virtual bool IsConcurrent() const { 73 return false; 74 } 75 virtual void MarkingPhase() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); 76 virtual void ReclaimPhase() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); 77 virtual void FinishPhase() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); … }
  • 8. Semi-Space Collector: Mark • If object A is in from_space – If two most significant bits of object A->monitor is not 3 • Copy object A to to_space or promoted_space A’ • Update object A->monitor. • Push New object A’ to mark_stack. • Else if object is not in Immune_region – Mark action same as mark_sweep action. * |33|22222222221111|1111110000000000| * |10|98765432109876|5432109876543210| * |11| object’s new location address >>2 |
  • 9. Semi-Space Collector: Reclaim • Sweep • BumpPointerSpace::Clear – madvise(Begin(), Limit() - Begin(), MADV_DONTNEED) madvise:: MADV_DONTNEED Subsequent accesses of pages in this range will succeed, but will result either in reloading of the memory contents from the underlying mapped file or zero-fill- on-demand pages for mappings without an underlying file.
  • 10. Optimization • Though just collector garbage of bump pointer space, the non moving space and main space mast be scanned and marked. This is inefficient. • RememberedSet is involved by Hiroshi Yamauchi. It is same to ModUnionTable. It trace the reference from non-moving space/main space to bump pointer space.
  • 11. Process Cards void Heap::ProcessCards(TimingLogger& timings, bool use_rem_sets) { // Clear cards and keep track of cards cleared in the mod-union table. for (const auto& space : continuous_spaces_) { accounting::ModUnionTable* table = FindModUnionTableFromSpace(space); + accounting::RememberedSet* rem_set = FindRememberedSetFromSpace(space); if (table != nullptr) { const char* name = space->IsZygoteSpace() ? "ZygoteModUnionClearCards" : "ImageModUnionClearCards"; TimingLogger::ScopedSplit split(name, &timings); table->ClearCards(); + } else if (use_rem_sets && rem_set != nullptr) { + DCHECK(collector::SemiSpace::kUseRememberedSet && collector_type_ == kCollectorTypeGSS) + << static_cast<int>(collector_type_); + TimingLogger::ScopedSplit split("AllocSpaceRemSetClearCards", &timings); + rem_set->ClearCards(); } else if (space->GetType() != space::kSpaceTypeBumpPointerSpace) { TimingLogger::ScopedSplit split("AllocSpaceClearCards", &timings); // No mod union table for the AllocSpace. Age the cards so that the GC knows that these cards // were dirty before the GC started. // TODO: Need to use atomic for the case where aged(cleaning thread) -> dirty(other thread) // -> clean(cleaning thread). // The races are we either end up with: Aged card, unaged card. Since we have the checkpoint // roots and then we scan / update mod union tables after. We will always scan either card. // If we end up with the non aged card, we scan it it in the pause. card_table_->ModifyCardsAtomic(space->Begin(), space->End(), AgeCardVisitor(), VoidFunctor()); } } }
  • 12. Update RememberedSet void RememberedSet::UpdateAndMarkReferences(MarkObjectCallback* callback, space::ContinuousSpace* target_space, void* arg) { CardTable* card_table = heap_->GetCardTable(); bool contains_reference_to_target_space = false; RememberedSetObjectVisitor obj_visitor(callback, target_space, &contains_reference_to_target_space, arg); SpaceBitmap* bitmap = space_->GetLiveBitmap(); CardSet remove_card_set; for (byte* const card_addr : dirty_cards_) { contains_reference_to_target_space = false; uintptr_t start = reinterpret_cast<uintptr_t>(card_table->AddrFromCard(card_addr)); DCHECK(space_->HasAddress(reinterpret_cast<mirror::Object*>(start))); bitmap->VisitMarkedRange(start, start + CardTable::kCardSize, obj_visitor); if (!contains_reference_to_target_space) { // It was in the dirty card set, but it didn't actually contain // a reference to the target space. So, remove it from the dirty // card set so we won't have to scan it again (unless it gets // dirty again.) remove_card_set.insert(card_addr); } } // Remove the cards that didn't contain a reference to the target // space from the dirty card set. for (byte* const card_addr : remove_card_set) { DCHECK(dirty_cards_.find(card_addr) != dirty_cards_.end()); dirty_cards_.erase(card_addr); } }
  • 13. GSS and Whole Heap Collection • If promotion bytes or large object bytes allocated exceeds threshold. GSS will do partial Mark Sweep + Semi-Space collector on whole heap.
  • 14. ZygoteCompactingCollector • When – When Zygote fork the first process. • How 1627 ZygoteCompactingCollector zygote_collector(this); 1628 zygote_collector.BuildBins(non_moving_space_); 1629 // Create a new bump pointer space which we will compact into. 1630 space::BumpPointerSpace target_space("zygote bump space", non_moving_space_->End(), non_moving_space_->Limit()); 1633 // Compact the bump pointer space to a new zygote bump pointer space. 1635 zygote_collector.SetFromSpace(bump_pointer_space_); 1636 zygote_collector.SetToSpace(&target_space); 1637 zygote_collector.Run(kGcCauseCollectorTransition, false);
  • 15. Backup 703 BoundedFifoPowerOfTwo<Object*, kFifoSize> prefetch_fifo; 705 for (;;) { 706 Object* obj = NULL; 708 while (!mark_stack_->IsEmpty() && prefetch_fifo.size() < kFifoSize) { 709 Object * obj = mark_stack_->PopBack(); 710 DCHECK(obj != NULL); 711 __builtin_prefetch(obj); 712 prefetch_fifo.push_back(obj); 713 } 714 if (prefetch_fifo.empty()) { 715 break; 716 } 717 obj = prefetch_fifo.front(); 718 prefetch_fifo.pop_front(); 737 ScanObject(obj); 738 } 740 }