summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-01-08 11:28:13 -0800
committerMathieu Chartier <mathieuc@google.com>2015-01-08 16:02:00 -0800
commit379d09fe3c3feb7c2a2fb5a3623689b5ace7e79b (patch)
tree680b4173130057a1f70ad321eaf4cfbeba0e291c
parentca7d89d09294254f16db170a53b0f8dfbf0213ac (diff)
downloadart-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.h6
-rw-r--r--runtime/gc/heap.cc14
-rw-r--r--runtime/gc/heap.h6
-rw-r--r--runtime/gc/space/malloc_space.cc10
-rw-r--r--runtime/gc/space/malloc_space.h4
-rw-r--r--runtime/mem_map.cc13
-rw-r--r--runtime/mem_map.h3
-rw-r--r--runtime/native/dalvik_system_VMRuntime.cc5
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"),