diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-01-08 11:28:13 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2015-01-08 16:02:00 -0800 |
commit | 379d09fe3c3feb7c2a2fb5a3623689b5ace7e79b (patch) | |
tree | 680b4173130057a1f70ad321eaf4cfbeba0e291c | |
parent | ca7d89d09294254f16db170a53b0f8dfbf0213ac (diff) | |
download | art-379d09fe3c3feb7c2a2fb5a3623689b5ace7e79b.zip art-379d09fe3c3feb7c2a2fb5a3623689b5ace7e79b.tar.gz art-379d09fe3c3feb7c2a2fb5a3623689b5ace7e79b.tar.bz2 |
Add clamp growth limit
Clamp growth limit shrinks the space memmaps to the current growth
limit. This reduces virtual memory usage for apps with small heaps.
Bug: 18387825
Bug: 17131630
Change-Id: I4a8fdc335d2c40492e991708adabcc46299efb7d
-rw-r--r-- | runtime/gc/accounting/space_bitmap.h | 6 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 14 | ||||
-rw-r--r-- | runtime/gc/heap.h | 6 | ||||
-rw-r--r-- | runtime/gc/space/malloc_space.cc | 10 | ||||
-rw-r--r-- | runtime/gc/space/malloc_space.h | 4 | ||||
-rw-r--r-- | runtime/mem_map.cc | 13 | ||||
-rw-r--r-- | runtime/mem_map.h | 3 | ||||
-rw-r--r-- | runtime/native/dalvik_system_VMRuntime.cc | 5 |
8 files changed, 60 insertions, 1 deletions
diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h index e73166b..7bc83ef 100644 --- a/runtime/gc/accounting/space_bitmap.h +++ b/runtime/gc/accounting/space_bitmap.h @@ -160,6 +160,12 @@ class SpaceBitmap { return IndexToOffset<uint64_t>(Size() / sizeof(intptr_t)); } + void SetHeapSize(size_t bytes) { + // TODO: Un-map the end of the mem map. + bitmap_size_ = OffsetToIndex(bytes) * sizeof(intptr_t); + CHECK_EQ(HeapSize(), bytes); + } + uintptr_t HeapBegin() const { return heap_begin_; } diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 2575676..db287d3 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -2978,6 +2978,20 @@ void Heap::GrowForUtilization(collector::GarbageCollector* collector_ran, } } +void Heap::ClampGrowthLimit() { + capacity_ = growth_limit_; + for (const auto& space : continuous_spaces_) { + if (space->IsMallocSpace()) { + gc::space::MallocSpace* malloc_space = space->AsMallocSpace(); + malloc_space->ClampGrowthLimit(); + } + } + // This space isn't added for performance reasons. + if (main_space_backup_.get() != nullptr) { + main_space_backup_->ClampGrowthLimit(); + } +} + void Heap::ClearGrowthLimit() { growth_limit_ = capacity_; for (const auto& space : continuous_spaces_) { diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 1738124..fc61fc5 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -302,6 +302,10 @@ class Heap { // implement dalvik.system.VMRuntime.clearGrowthLimit. void ClearGrowthLimit(); + // Make the current growth limit the new maximum capacity, unmaps pages at the end of spaces + // which will never be used. Used to implement dalvik.system.VMRuntime.clampGrowthLimit. + void ClampGrowthLimit(); + // Target ideal heap utilization ratio, implements // dalvik.system.VMRuntime.getTargetHeapUtilization. double GetTargetHeapUtilization() const { @@ -902,7 +906,7 @@ class Heap { collector::GcType next_gc_type_; // Maximum size that the heap can reach. - const size_t capacity_; + size_t capacity_; // The size the heap is limited to. This is initially smaller than capacity, but for largeHeap // programs it is "cleared" making it the same as capacity. diff --git a/runtime/gc/space/malloc_space.cc b/runtime/gc/space/malloc_space.cc index 7905bb4..9bbbb3c 100644 --- a/runtime/gc/space/malloc_space.cc +++ b/runtime/gc/space/malloc_space.cc @@ -248,6 +248,16 @@ void MallocSpace::SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* ar context->freed.bytes += space->FreeList(self, num_ptrs, ptrs); } +void MallocSpace::ClampGrowthLimit() { + size_t new_capacity = Capacity(); + CHECK_LE(new_capacity, NonGrowthLimitCapacity()); + GetLiveBitmap()->SetHeapSize(new_capacity); + GetMarkBitmap()->SetHeapSize(new_capacity); + GetMemMap()->SetSize(new_capacity); + limit_ = Begin() + new_capacity; + CHECK(temp_bitmap_.get() == nullptr); +} + } // namespace space } // namespace gc } // namespace art diff --git a/runtime/gc/space/malloc_space.h b/runtime/gc/space/malloc_space.h index 2fbd5f0..06239e5 100644 --- a/runtime/gc/space/malloc_space.h +++ b/runtime/gc/space/malloc_space.h @@ -110,6 +110,10 @@ class MallocSpace : public ContinuousMemMapAllocSpace { return GetMemMap()->Size(); } + // Change the non growth limit capacity by shrinking or expanding the map. Currently, only + // shrinking is supported. + void ClampGrowthLimit(); + void Dump(std::ostream& os) const; void SetGrowthLimit(size_t growth_limit); diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index 8303f84..a722813 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -665,6 +665,19 @@ void MemMap::Shutdown() { maps_ = nullptr; } +void MemMap::SetSize(size_t new_size) { + if (new_size == base_size_) { + return; + } + CHECK_ALIGNED(new_size, kPageSize); + CHECK_EQ(base_size_, size_) << "Unsupported"; + CHECK_LE(new_size, base_size_); + CHECK_EQ(munmap(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(BaseBegin()) + new_size), + base_size_ - new_size), 0) << new_size << " " << base_size_; + base_size_ = new_size; + size_ = new_size; +} + std::ostream& operator<<(std::ostream& os, const MemMap& mem_map) { os << StringPrintf("[MemMap: %p-%p prot=0x%x %s]", mem_map.BaseBegin(), mem_map.BaseEnd(), mem_map.GetProtect(), diff --git a/runtime/mem_map.h b/runtime/mem_map.h index 9b003aa..dc337e0 100644 --- a/runtime/mem_map.h +++ b/runtime/mem_map.h @@ -107,6 +107,9 @@ class MemMap { return size_; } + // Resize the mem-map by unmapping pages at the end. Currently only supports shrinking. + void SetSize(size_t new_size); + uint8_t* End() const { return Begin() + Size(); } diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index f503b35..471aa9c 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -134,6 +134,10 @@ static void VMRuntime_clearGrowthLimit(JNIEnv*, jobject) { Runtime::Current()->GetHeap()->ClearGrowthLimit(); } +static void VMRuntime_clampGrowthLimit(JNIEnv*, jobject) { + Runtime::Current()->GetHeap()->ClampGrowthLimit(); +} + static jboolean VMRuntime_isDebuggerActive(JNIEnv*, jobject) { return Dbg::IsDebuggerActive(); } @@ -577,6 +581,7 @@ static jstring VMRuntime_getCurrentInstructionSet(JNIEnv* env, jclass) { static JNINativeMethod gMethods[] = { NATIVE_METHOD(VMRuntime, addressOf, "!(Ljava/lang/Object;)J"), NATIVE_METHOD(VMRuntime, bootClassPath, "()Ljava/lang/String;"), + NATIVE_METHOD(VMRuntime, clampGrowthLimit, "()V"), NATIVE_METHOD(VMRuntime, classPath, "()Ljava/lang/String;"), NATIVE_METHOD(VMRuntime, clearGrowthLimit, "()V"), NATIVE_METHOD(VMRuntime, concurrentGC, "()V"), |