1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <algorithm>
18
19 #include "base/metrics/metrics.h"
20 #include "class_linker-inl.h"
21 #include "common_runtime_test.h"
22 #include "gc/accounting/card_table-inl.h"
23 #include "gc/accounting/space_bitmap-inl.h"
24 #include "handle_scope-inl.h"
25 #include "mirror/class-inl.h"
26 #include "mirror/object-inl.h"
27 #include "mirror/object_array-alloc-inl.h"
28 #include "mirror/object_array-inl.h"
29 #include "scoped_thread_state_change-inl.h"
30
31 namespace art HIDDEN {
32 namespace gc {
33
34 class HeapTest : public CommonRuntimeTest {
35 public:
HeapTest()36 HeapTest() {
37 use_boot_image_ = true; // Make the Runtime creation cheaper.
38 }
39
SetUp()40 void SetUp() override {
41 MemMap::Init();
42 std::string error_msg;
43 // Reserve the preferred address to force the heap to use another one for testing.
44 reserved_ = MemMap::MapAnonymous("ReserveMap",
45 gc::Heap::kPreferredAllocSpaceBegin,
46 16 * KB,
47 PROT_READ,
48 /*low_4gb=*/true,
49 /*reuse=*/false,
50 /*reservation=*/nullptr,
51 &error_msg);
52 // There is no guarantee that reserved_ will be valid (due to ASLR). See b/175018342.
53 CommonRuntimeTest::SetUp();
54 }
55
56 private:
57 MemMap reserved_;
58 };
59
TEST_F(HeapTest,ClearGrowthLimit)60 TEST_F(HeapTest, ClearGrowthLimit) {
61 Heap* heap = Runtime::Current()->GetHeap();
62 int64_t max_memory_before = heap->GetMaxMemory();
63 int64_t total_memory_before = heap->GetTotalMemory();
64 heap->ClearGrowthLimit();
65 int64_t max_memory_after = heap->GetMaxMemory();
66 int64_t total_memory_after = heap->GetTotalMemory();
67 EXPECT_GE(max_memory_after, max_memory_before);
68 EXPECT_GE(total_memory_after, total_memory_before);
69 }
70
TEST_F(HeapTest,GarbageCollectClassLinkerInit)71 TEST_F(HeapTest, GarbageCollectClassLinkerInit) {
72 {
73 ScopedObjectAccess soa(Thread::Current());
74 // garbage is created during ClassLinker::Init()
75 constexpr size_t kNumArrays = 1024;
76 constexpr size_t kNumElements = 2048;
77 StackHandleScope<1> hs(soa.Self());
78 Handle<mirror::Class> c(
79 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
80 for (size_t i = 0; i < kNumArrays; ++i) {
81 StackHandleScope<1> hs2(soa.Self());
82 Handle<mirror::ObjectArray<mirror::Object>> array(hs2.NewHandle(
83 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c.Get(), kNumElements)));
84 for (size_t j = 0; j < kNumElements; ++j) {
85 ObjPtr<mirror::String> string =
86 mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!");
87 // handle scope operator -> deferences the handle scope before running the method.
88 array->Set<false>(j, string);
89 }
90 }
91 }
92 Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ false);
93 }
94
TEST_F(HeapTest,HeapBitmapCapacityTest)95 TEST_F(HeapTest, HeapBitmapCapacityTest) {
96 uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x1000);
97 const size_t heap_capacity = kObjectAlignment * (sizeof(intptr_t) * 8 + 1);
98 accounting::ContinuousSpaceBitmap bitmap(
99 accounting::ContinuousSpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
100 mirror::Object* fake_end_of_heap_object =
101 reinterpret_cast<mirror::Object*>(&heap_begin[heap_capacity - kObjectAlignment]);
102 bitmap.Set(fake_end_of_heap_object);
103 }
104
TEST_F(HeapTest,DumpGCPerformanceOnShutdown)105 TEST_F(HeapTest, DumpGCPerformanceOnShutdown) {
106 Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ false);
107 Runtime::Current()->SetDumpGCPerformanceOnShutdown(true);
108 }
109
AnyIsFalse(bool x,bool y)110 bool AnyIsFalse(bool x, bool y) { return !x || !y; }
111
TEST_F(HeapTest,GCMetrics)112 TEST_F(HeapTest, GCMetrics) {
113 // Allocate a lot of object arrays to be collected (to ensure the garbage collection is long
114 // enough for the timing metrics to be non-zero), then trigger garbage collection, and check that
115 // GC metrics are updated (where applicable).
116 Heap* heap = Runtime::Current()->GetHeap();
117 {
118 constexpr size_t kNumArrays = 32768;
119 constexpr size_t kNumElements = 4;
120 ScopedObjectAccess soa(Thread::Current());
121 StackHandleScope<kNumArrays + 1> hs(soa.Self());
122 Handle<mirror::Class> c(
123 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
124 for (size_t i = 0; i < kNumArrays; i++) {
125 MutableHandle<mirror::ObjectArray<mirror::Object>> array(hs.NewHandle(
126 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c.Get(), kNumElements)));
127 // Perform another allocation so that the previous object array becomes garbage,
128 // forcing all the components of the GC to be involved due to the mix of reachable
129 // and unreachable objects.
130 array.Assign(mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c.Get(), kNumElements));
131 for (size_t j = 0; j < kNumElements; j++) {
132 array->Set<false>(j, array.Get());
133 }
134 }
135
136 // Do one GC while the temporary objects are reachable, forcing the GC to scan something.
137 // The subsequent GC at line 127 may not scan anything but will certainly free some bytes.
138 // Together the two GCs ensure success of the test.
139 heap->CollectGarbage(/* clear_soft_references= */ false);
140 }
141 heap->CollectGarbage(/* clear_soft_references= */ false);
142
143 // ART Metrics.
144 metrics::ArtMetrics* metrics = Runtime::Current()->GetMetrics();
145 // ART full-heap GC metrics.
146 metrics::MetricsBase<int64_t>* full_gc_collection_time = metrics->FullGcCollectionTime();
147 metrics::MetricsBase<uint64_t>* full_gc_count = metrics->FullGcCount();
148 metrics::MetricsBase<uint64_t>* full_gc_count_delta = metrics->FullGcCountDelta();
149 metrics::MetricsBase<int64_t>* full_gc_throughput = metrics->FullGcThroughput();
150 metrics::MetricsBase<int64_t>* full_gc_tracing_throughput = metrics->FullGcTracingThroughput();
151 metrics::MetricsBase<uint64_t>* full_gc_throughput_avg = metrics->FullGcThroughputAvg();
152 metrics::MetricsBase<uint64_t>* full_gc_tracing_throughput_avg =
153 metrics->FullGcTracingThroughputAvg();
154 metrics::MetricsBase<uint64_t>* full_gc_scanned_bytes = metrics->FullGcScannedBytes();
155 metrics::MetricsBase<uint64_t>* full_gc_scanned_bytes_delta = metrics->FullGcScannedBytesDelta();
156 metrics::MetricsBase<uint64_t>* full_gc_freed_bytes = metrics->FullGcFreedBytes();
157 metrics::MetricsBase<uint64_t>* full_gc_freed_bytes_delta = metrics->FullGcFreedBytesDelta();
158 metrics::MetricsBase<uint64_t>* full_gc_duration = metrics->FullGcDuration();
159 metrics::MetricsBase<uint64_t>* full_gc_duration_delta = metrics->FullGcDurationDelta();
160 metrics::MetricsBase<uint64_t>* full_gc_app_slow_path_duration_delta =
161 metrics->AppSlowPathDuringFullGcDurationDelta();
162 // ART young-generation GC metrics.
163 metrics::MetricsBase<int64_t>* young_gc_collection_time = metrics->YoungGcCollectionTime();
164 metrics::MetricsBase<uint64_t>* young_gc_count = metrics->YoungGcCount();
165 metrics::MetricsBase<uint64_t>* young_gc_count_delta = metrics->YoungGcCountDelta();
166 metrics::MetricsBase<int64_t>* young_gc_throughput = metrics->YoungGcThroughput();
167 metrics::MetricsBase<int64_t>* young_gc_tracing_throughput = metrics->YoungGcTracingThroughput();
168 metrics::MetricsBase<uint64_t>* young_gc_throughput_avg = metrics->YoungGcThroughputAvg();
169 metrics::MetricsBase<uint64_t>* young_gc_tracing_throughput_avg =
170 metrics->YoungGcTracingThroughputAvg();
171 metrics::MetricsBase<uint64_t>* young_gc_scanned_bytes = metrics->YoungGcScannedBytes();
172 metrics::MetricsBase<uint64_t>* young_gc_scanned_bytes_delta =
173 metrics->YoungGcScannedBytesDelta();
174 metrics::MetricsBase<uint64_t>* young_gc_freed_bytes = metrics->YoungGcFreedBytes();
175 metrics::MetricsBase<uint64_t>* young_gc_freed_bytes_delta = metrics->YoungGcFreedBytesDelta();
176 metrics::MetricsBase<uint64_t>* young_gc_duration = metrics->YoungGcDuration();
177 metrics::MetricsBase<uint64_t>* young_gc_duration_delta = metrics->YoungGcDurationDelta();
178 metrics::MetricsBase<uint64_t>* young_gc_app_slow_path_duration_delta =
179 metrics->AppSlowPathDuringYoungGcDurationDelta();
180
181 CollectorType fg_collector_type = heap->GetForegroundCollectorType();
182 if (fg_collector_type == kCollectorTypeCC || fg_collector_type == kCollectorTypeCMC) {
183 // Only the Concurrent Copying and Concurrent Mark-Compact collectors enable
184 // GC metrics at the moment.
185 if (heap->GetUseGenerational()) {
186 // Check that full-heap and/or young-generation GC metrics are non-null
187 // after triggering the collection.
188 EXPECT_PRED2(
189 AnyIsFalse, full_gc_collection_time->IsNull(), young_gc_collection_time->IsNull());
190 EXPECT_PRED2(AnyIsFalse, full_gc_count->IsNull(), young_gc_count->IsNull());
191 EXPECT_PRED2(AnyIsFalse, full_gc_count_delta->IsNull(), young_gc_count_delta->IsNull());
192 EXPECT_PRED2(AnyIsFalse, full_gc_throughput->IsNull(), young_gc_throughput->IsNull());
193 EXPECT_PRED2(
194 AnyIsFalse, full_gc_tracing_throughput->IsNull(), young_gc_tracing_throughput->IsNull());
195 EXPECT_PRED2(AnyIsFalse, full_gc_throughput_avg->IsNull(), young_gc_throughput_avg->IsNull());
196 EXPECT_PRED2(AnyIsFalse,
197 full_gc_tracing_throughput_avg->IsNull(),
198 young_gc_tracing_throughput_avg->IsNull());
199 EXPECT_PRED2(AnyIsFalse, full_gc_scanned_bytes->IsNull(), young_gc_scanned_bytes->IsNull());
200 EXPECT_PRED2(AnyIsFalse,
201 full_gc_scanned_bytes_delta->IsNull(),
202 young_gc_scanned_bytes_delta->IsNull());
203 EXPECT_PRED2(AnyIsFalse, full_gc_freed_bytes->IsNull(), young_gc_freed_bytes->IsNull());
204 EXPECT_PRED2(
205 AnyIsFalse, full_gc_freed_bytes_delta->IsNull(), young_gc_freed_bytes_delta->IsNull());
206 EXPECT_PRED2(AnyIsFalse, full_gc_duration->IsNull(), young_gc_duration->IsNull());
207 EXPECT_PRED2(AnyIsFalse, full_gc_duration_delta->IsNull(), young_gc_duration_delta->IsNull());
208 EXPECT_PRED2(AnyIsFalse,
209 full_gc_app_slow_path_duration_delta->IsNull(),
210 young_gc_app_slow_path_duration_delta->IsNull());
211 } else {
212 // Check that only full-heap GC metrics are non-null after triggering the collection.
213 EXPECT_FALSE(full_gc_collection_time->IsNull());
214 EXPECT_FALSE(full_gc_count->IsNull());
215 EXPECT_FALSE(full_gc_count_delta->IsNull());
216 EXPECT_FALSE(full_gc_throughput->IsNull());
217 EXPECT_FALSE(full_gc_tracing_throughput->IsNull());
218 EXPECT_FALSE(full_gc_throughput_avg->IsNull());
219 EXPECT_FALSE(full_gc_tracing_throughput_avg->IsNull());
220 EXPECT_FALSE(full_gc_scanned_bytes->IsNull());
221 EXPECT_FALSE(full_gc_scanned_bytes_delta->IsNull());
222 EXPECT_FALSE(full_gc_freed_bytes->IsNull());
223 EXPECT_FALSE(full_gc_freed_bytes_delta->IsNull());
224 EXPECT_FALSE(full_gc_duration->IsNull());
225 EXPECT_FALSE(full_gc_duration_delta->IsNull());
226 EXPECT_FALSE(full_gc_app_slow_path_duration_delta->IsNull());
227
228 EXPECT_TRUE(young_gc_collection_time->IsNull());
229 EXPECT_TRUE(young_gc_count->IsNull());
230 EXPECT_TRUE(young_gc_count_delta->IsNull());
231 EXPECT_TRUE(young_gc_throughput->IsNull());
232 EXPECT_TRUE(young_gc_tracing_throughput->IsNull());
233 EXPECT_TRUE(young_gc_throughput_avg->IsNull());
234 EXPECT_TRUE(young_gc_tracing_throughput_avg->IsNull());
235 EXPECT_TRUE(young_gc_scanned_bytes->IsNull());
236 EXPECT_TRUE(young_gc_scanned_bytes_delta->IsNull());
237 EXPECT_TRUE(young_gc_freed_bytes->IsNull());
238 EXPECT_TRUE(young_gc_freed_bytes_delta->IsNull());
239 EXPECT_TRUE(young_gc_duration->IsNull());
240 EXPECT_TRUE(young_gc_duration_delta->IsNull());
241 EXPECT_TRUE(young_gc_app_slow_path_duration_delta->IsNull());
242 }
243 } else {
244 // Check that all metrics are null after triggering the collection.
245 EXPECT_TRUE(full_gc_collection_time->IsNull());
246 EXPECT_TRUE(full_gc_count->IsNull());
247 EXPECT_TRUE(full_gc_count_delta->IsNull());
248 EXPECT_TRUE(full_gc_throughput->IsNull());
249 EXPECT_TRUE(full_gc_tracing_throughput->IsNull());
250 EXPECT_TRUE(full_gc_throughput_avg->IsNull());
251 EXPECT_TRUE(full_gc_tracing_throughput_avg->IsNull());
252 EXPECT_TRUE(full_gc_scanned_bytes->IsNull());
253 EXPECT_TRUE(full_gc_scanned_bytes_delta->IsNull());
254 EXPECT_TRUE(full_gc_freed_bytes->IsNull());
255 EXPECT_TRUE(full_gc_freed_bytes_delta->IsNull());
256 EXPECT_TRUE(full_gc_duration->IsNull());
257 EXPECT_TRUE(full_gc_duration_delta->IsNull());
258 EXPECT_TRUE(full_gc_app_slow_path_duration_delta->IsNull());
259
260 EXPECT_TRUE(young_gc_collection_time->IsNull());
261 EXPECT_TRUE(young_gc_count->IsNull());
262 EXPECT_TRUE(young_gc_count_delta->IsNull());
263 EXPECT_TRUE(young_gc_throughput->IsNull());
264 EXPECT_TRUE(young_gc_tracing_throughput->IsNull());
265 EXPECT_TRUE(young_gc_throughput_avg->IsNull());
266 EXPECT_TRUE(young_gc_tracing_throughput_avg->IsNull());
267 EXPECT_TRUE(young_gc_scanned_bytes->IsNull());
268 EXPECT_TRUE(young_gc_scanned_bytes_delta->IsNull());
269 EXPECT_TRUE(young_gc_freed_bytes->IsNull());
270 EXPECT_TRUE(young_gc_freed_bytes_delta->IsNull());
271 EXPECT_TRUE(young_gc_duration->IsNull());
272 EXPECT_TRUE(young_gc_duration_delta->IsNull());
273 EXPECT_TRUE(young_gc_app_slow_path_duration_delta->IsNull());
274 }
275 }
276
277 class ZygoteHeapTest : public CommonRuntimeTest {
278 public:
ZygoteHeapTest()279 ZygoteHeapTest() {
280 use_boot_image_ = true; // Make the Runtime creation cheaper.
281 }
282
SetUpRuntimeOptions(RuntimeOptions * options)283 void SetUpRuntimeOptions(RuntimeOptions* options) override {
284 CommonRuntimeTest::SetUpRuntimeOptions(options);
285 options->push_back(std::make_pair("-Xzygote", nullptr));
286 }
287 };
288
TEST_F(ZygoteHeapTest,PreZygoteFork)289 TEST_F(ZygoteHeapTest, PreZygoteFork) {
290 // Exercise Heap::PreZygoteFork() to check it does not crash.
291 Runtime::Current()->GetHeap()->PreZygoteFork();
292 }
293
294 } // namespace gc
295 } // namespace art
296