SlideShare a Scribd company logo
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

PDF
Dawid Weiss- Finite state automata in lucene
PPTX
Introduction to spark
PDF
Pl sql-ch1
PPTX
Types of keys in dbms
PDF
A Tale of Three Apache Spark APIs: RDDs, DataFrames, and Datasets with Jules ...
PPTX
Linking in MS-Dos System
PDF
Debugging Apache Spark
PDF
Understanding Monitor in Dalvik
Dawid Weiss- Finite state automata in lucene
Introduction to spark
Pl sql-ch1
Types of keys in dbms
A Tale of Three Apache Spark APIs: RDDs, DataFrames, and Datasets with Jules ...
Linking in MS-Dos System
Debugging Apache Spark
Understanding Monitor in Dalvik

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

PPT
Gc in android
PPT
«Большие объёмы данных и сборка мусора в Java
PPT
Basic Garbage Collection Techniques
ODP
Garbage Collection in Hotspot JVM
PDF
Garbage Collection: the Useful Parts - Martijn Verburg & Dr John Oliver (jCla...
PPTX
Garbage collection algorithms
PDF
Understanding Java Garbage Collection - And What You Can Do About It
PDF
Jvm heap
PDF
What you need to know about GC
PDF
Understanding GC, JavaOne 2017
PDF
Tuning IBMs Generational GC
PDF
GC in Smalltalk
PDF
Advancements ingc andc4overview_linkedin_oct2017
PPT
Garbage collection in JVM
PPTX
Garbage collection
PPTX
Gc algorithm inside_dot_net
PDF
Hotspot Garbage Collection - The Useful Parts
PDF
Garbage Collection
PPTX
Jvm lecture
PPTX
A History of Modern Garbage Collection Techniques
Gc in android
«Большие объёмы данных и сборка мусора в Java
Basic Garbage Collection Techniques
Garbage Collection in Hotspot JVM
Garbage Collection: the Useful Parts - Martijn Verburg & Dr John Oliver (jCla...
Garbage collection algorithms
Understanding Java Garbage Collection - And What You Can Do About It
Jvm heap
What you need to know about GC
Understanding GC, JavaOne 2017
Tuning IBMs Generational GC
GC in Smalltalk
Advancements ingc andc4overview_linkedin_oct2017
Garbage collection in JVM
Garbage collection
Gc algorithm inside_dot_net
Hotspot Garbage Collection - The Useful Parts
Garbage Collection
Jvm lecture
A History of Modern Garbage Collection Techniques
Ad

Recently uploaded (6)

PDF
6-UseCfgfhgfhgfhgfhgfhfhhaseActivity.pdf
PPTX
Introduction to Packet Tracer Course Overview - Aug 21 (1).pptx
PPTX
ASMS Telecommunication company Profile
DOC
证书学历UoA毕业证,澳大利亚中汇学院毕业证国外大学毕业证
PDF
Lesson 13- HEREDITY _ pedSAWEREGFVCXZDSASEWFigree.pdf
DOC
Camb毕业证学历认证,格罗斯泰斯特主教大学毕业证仿冒文凭毕业证
6-UseCfgfhgfhgfhgfhgfhfhhaseActivity.pdf
Introduction to Packet Tracer Course Overview - Aug 21 (1).pptx
ASMS Telecommunication company Profile
证书学历UoA毕业证,澳大利亚中汇学院毕业证国外大学毕业证
Lesson 13- HEREDITY _ pedSAWEREGFVCXZDSASEWFigree.pdf
Camb毕业证学历认证,格罗斯泰斯特主教大学毕业证仿冒文凭毕业证
Ad

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 }