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 
76     StackHandleScope<1> hs(soa.Self());
77     Handle<mirror::Class> c(
78         hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
79     for (size_t i = 0; i < 1024; ++i) {
80       StackHandleScope<1> hs2(soa.Self());
81       Handle<mirror::ObjectArray<mirror::Object>> array(hs2.NewHandle(
82           mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c.Get(), 2048)));
83       for (size_t j = 0; j < 2048; ++j) {
84         ObjPtr<mirror::String> string =
85             mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!");
86         // handle scope operator -> deferences the handle scope before running the method.
87         array->Set<false>(j, string);
88       }
89     }
90   }
91   Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ false);
92 }
93 
TEST_F(HeapTest,HeapBitmapCapacityTest)94 TEST_F(HeapTest, HeapBitmapCapacityTest) {
95   uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x1000);
96   const size_t heap_capacity = kObjectAlignment * (sizeof(intptr_t) * 8 + 1);
97   accounting::ContinuousSpaceBitmap bitmap(
98       accounting::ContinuousSpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
99   mirror::Object* fake_end_of_heap_object =
100       reinterpret_cast<mirror::Object*>(&heap_begin[heap_capacity - kObjectAlignment]);
101   bitmap.Set(fake_end_of_heap_object);
102 }
103 
TEST_F(HeapTest,DumpGCPerformanceOnShutdown)104 TEST_F(HeapTest, DumpGCPerformanceOnShutdown) {
105   Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ false);
106   Runtime::Current()->SetDumpGCPerformanceOnShutdown(true);
107 }
108 
AnyIsFalse(bool x,bool y)109 bool AnyIsFalse(bool x, bool y) { return !x || !y; }
110 
TEST_F(HeapTest,GCMetrics)111 TEST_F(HeapTest, GCMetrics) {
112   // Allocate a few string objects (to be collected), then trigger garbage
113   // collection, and check that GC metrics are updated (where applicable).
114   Heap* heap = Runtime::Current()->GetHeap();
115   {
116     constexpr const size_t kNumObj = 128;
117     ScopedObjectAccess soa(Thread::Current());
118     StackHandleScope<kNumObj> hs(soa.Self());
119     for (size_t i = 0u; i < kNumObj; ++i) {
120       Handle<mirror::String> string [[maybe_unused]] (
121           hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "test")));
122     }
123     // Do one GC while the temporary objects are reachable, forcing the GC to scan something.
124     // The subsequent GC at line 127 may not scan anything but will certainly free some bytes.
125     // Together the two GCs ensure success of the test.
126     heap->CollectGarbage(/* clear_soft_references= */ false);
127   }
128   heap->CollectGarbage(/* clear_soft_references= */ false);
129 
130   // ART Metrics.
131   metrics::ArtMetrics* metrics = Runtime::Current()->GetMetrics();
132   // ART full-heap GC metrics.
133   metrics::MetricsBase<int64_t>* full_gc_collection_time = metrics->FullGcCollectionTime();
134   metrics::MetricsBase<uint64_t>* full_gc_count = metrics->FullGcCount();
135   metrics::MetricsBase<uint64_t>* full_gc_count_delta = metrics->FullGcCountDelta();
136   metrics::MetricsBase<int64_t>* full_gc_throughput = metrics->FullGcThroughput();
137   metrics::MetricsBase<int64_t>* full_gc_tracing_throughput = metrics->FullGcTracingThroughput();
138   metrics::MetricsBase<uint64_t>* full_gc_throughput_avg = metrics->FullGcThroughputAvg();
139   metrics::MetricsBase<uint64_t>* full_gc_tracing_throughput_avg =
140       metrics->FullGcTracingThroughputAvg();
141   metrics::MetricsBase<uint64_t>* full_gc_scanned_bytes = metrics->FullGcScannedBytes();
142   metrics::MetricsBase<uint64_t>* full_gc_scanned_bytes_delta = metrics->FullGcScannedBytesDelta();
143   metrics::MetricsBase<uint64_t>* full_gc_freed_bytes = metrics->FullGcFreedBytes();
144   metrics::MetricsBase<uint64_t>* full_gc_freed_bytes_delta = metrics->FullGcFreedBytesDelta();
145   metrics::MetricsBase<uint64_t>* full_gc_duration = metrics->FullGcDuration();
146   metrics::MetricsBase<uint64_t>* full_gc_duration_delta = metrics->FullGcDurationDelta();
147   // ART young-generation GC metrics.
148   metrics::MetricsBase<int64_t>* young_gc_collection_time = metrics->YoungGcCollectionTime();
149   metrics::MetricsBase<uint64_t>* young_gc_count = metrics->YoungGcCount();
150   metrics::MetricsBase<uint64_t>* young_gc_count_delta = metrics->YoungGcCountDelta();
151   metrics::MetricsBase<int64_t>* young_gc_throughput = metrics->YoungGcThroughput();
152   metrics::MetricsBase<int64_t>* young_gc_tracing_throughput = metrics->YoungGcTracingThroughput();
153   metrics::MetricsBase<uint64_t>* young_gc_throughput_avg = metrics->YoungGcThroughputAvg();
154   metrics::MetricsBase<uint64_t>* young_gc_tracing_throughput_avg =
155       metrics->YoungGcTracingThroughputAvg();
156   metrics::MetricsBase<uint64_t>* young_gc_scanned_bytes = metrics->YoungGcScannedBytes();
157   metrics::MetricsBase<uint64_t>* young_gc_scanned_bytes_delta =
158       metrics->YoungGcScannedBytesDelta();
159   metrics::MetricsBase<uint64_t>* young_gc_freed_bytes = metrics->YoungGcFreedBytes();
160   metrics::MetricsBase<uint64_t>* young_gc_freed_bytes_delta = metrics->YoungGcFreedBytesDelta();
161   metrics::MetricsBase<uint64_t>* young_gc_duration = metrics->YoungGcDuration();
162   metrics::MetricsBase<uint64_t>* young_gc_duration_delta = metrics->YoungGcDurationDelta();
163 
164   CollectorType fg_collector_type = heap->GetForegroundCollectorType();
165   if (fg_collector_type == kCollectorTypeCC || fg_collector_type == kCollectorTypeCMC) {
166     // Only the Concurrent Copying and Concurrent Mark-Compact collectors enable
167     // GC metrics at the moment.
168     if (heap->GetUseGenerationalCC()) {
169       // Check that full-heap and/or young-generation GC metrics are non-null
170       // after trigerring the collection.
171       EXPECT_PRED2(
172           AnyIsFalse, full_gc_collection_time->IsNull(), young_gc_collection_time->IsNull());
173       EXPECT_PRED2(AnyIsFalse, full_gc_count->IsNull(), young_gc_count->IsNull());
174       EXPECT_PRED2(AnyIsFalse, full_gc_count_delta->IsNull(), young_gc_count_delta->IsNull());
175       EXPECT_PRED2(AnyIsFalse, full_gc_throughput->IsNull(), young_gc_throughput->IsNull());
176       EXPECT_PRED2(
177           AnyIsFalse, full_gc_tracing_throughput->IsNull(), young_gc_tracing_throughput->IsNull());
178       EXPECT_PRED2(AnyIsFalse, full_gc_throughput_avg->IsNull(), young_gc_throughput_avg->IsNull());
179       EXPECT_PRED2(AnyIsFalse,
180                    full_gc_tracing_throughput_avg->IsNull(),
181                    young_gc_tracing_throughput_avg->IsNull());
182       EXPECT_PRED2(AnyIsFalse, full_gc_scanned_bytes->IsNull(), young_gc_scanned_bytes->IsNull());
183       EXPECT_PRED2(AnyIsFalse,
184                    full_gc_scanned_bytes_delta->IsNull(),
185                    young_gc_scanned_bytes_delta->IsNull());
186       EXPECT_PRED2(AnyIsFalse, full_gc_freed_bytes->IsNull(), young_gc_freed_bytes->IsNull());
187       EXPECT_PRED2(
188           AnyIsFalse, full_gc_freed_bytes_delta->IsNull(), young_gc_freed_bytes_delta->IsNull());
189       // We have observed that sometimes the GC duration (both for full-heap and
190       // young-generation collections) is null (b/271112044). Temporarily
191       // suspend the following checks while we investigate.
192       //
193       // TODO(b/271112044): Investigate and adjust these expectations and/or the
194       // corresponding metric logic.
195 #if 0
196       EXPECT_PRED2(AnyIsFalse, full_gc_duration->IsNull(), young_gc_duration->IsNull());
197       EXPECT_PRED2(AnyIsFalse, full_gc_duration_delta->IsNull(), young_gc_duration_delta->IsNull());
198 #endif
199     } else {
200       // Check that only full-heap GC metrics are non-null after trigerring the collection.
201       EXPECT_FALSE(full_gc_collection_time->IsNull());
202       EXPECT_FALSE(full_gc_count->IsNull());
203       EXPECT_FALSE(full_gc_count_delta->IsNull());
204       EXPECT_FALSE(full_gc_throughput->IsNull());
205       EXPECT_FALSE(full_gc_tracing_throughput->IsNull());
206       EXPECT_FALSE(full_gc_throughput_avg->IsNull());
207       EXPECT_FALSE(full_gc_tracing_throughput_avg->IsNull());
208       EXPECT_FALSE(full_gc_scanned_bytes->IsNull());
209       EXPECT_FALSE(full_gc_scanned_bytes_delta->IsNull());
210       EXPECT_FALSE(full_gc_freed_bytes->IsNull());
211       EXPECT_FALSE(full_gc_freed_bytes_delta->IsNull());
212       EXPECT_FALSE(full_gc_duration->IsNull());
213       EXPECT_FALSE(full_gc_duration_delta->IsNull());
214 
215       EXPECT_TRUE(young_gc_collection_time->IsNull());
216       EXPECT_TRUE(young_gc_count->IsNull());
217       EXPECT_TRUE(young_gc_count_delta->IsNull());
218       EXPECT_TRUE(young_gc_throughput->IsNull());
219       EXPECT_TRUE(young_gc_tracing_throughput->IsNull());
220       EXPECT_TRUE(young_gc_throughput_avg->IsNull());
221       EXPECT_TRUE(young_gc_tracing_throughput_avg->IsNull());
222       EXPECT_TRUE(young_gc_scanned_bytes->IsNull());
223       EXPECT_TRUE(young_gc_scanned_bytes_delta->IsNull());
224       EXPECT_TRUE(young_gc_freed_bytes->IsNull());
225       EXPECT_TRUE(young_gc_freed_bytes_delta->IsNull());
226       EXPECT_TRUE(young_gc_duration->IsNull());
227       EXPECT_TRUE(young_gc_duration_delta->IsNull());
228     }
229   } else {
230     // Check that all metrics are null after trigerring the collection.
231     EXPECT_TRUE(full_gc_collection_time->IsNull());
232     EXPECT_TRUE(full_gc_count->IsNull());
233     EXPECT_TRUE(full_gc_count_delta->IsNull());
234     EXPECT_TRUE(full_gc_throughput->IsNull());
235     EXPECT_TRUE(full_gc_tracing_throughput->IsNull());
236     EXPECT_TRUE(full_gc_throughput_avg->IsNull());
237     EXPECT_TRUE(full_gc_tracing_throughput_avg->IsNull());
238     EXPECT_TRUE(full_gc_scanned_bytes->IsNull());
239     EXPECT_TRUE(full_gc_scanned_bytes_delta->IsNull());
240     EXPECT_TRUE(full_gc_freed_bytes->IsNull());
241     EXPECT_TRUE(full_gc_freed_bytes_delta->IsNull());
242     EXPECT_TRUE(full_gc_duration->IsNull());
243     EXPECT_TRUE(full_gc_duration_delta->IsNull());
244 
245     EXPECT_TRUE(young_gc_collection_time->IsNull());
246     EXPECT_TRUE(young_gc_count->IsNull());
247     EXPECT_TRUE(young_gc_count_delta->IsNull());
248     EXPECT_TRUE(young_gc_throughput->IsNull());
249     EXPECT_TRUE(young_gc_tracing_throughput->IsNull());
250     EXPECT_TRUE(young_gc_throughput_avg->IsNull());
251     EXPECT_TRUE(young_gc_tracing_throughput_avg->IsNull());
252     EXPECT_TRUE(young_gc_scanned_bytes->IsNull());
253     EXPECT_TRUE(young_gc_scanned_bytes_delta->IsNull());
254     EXPECT_TRUE(young_gc_freed_bytes->IsNull());
255     EXPECT_TRUE(young_gc_freed_bytes_delta->IsNull());
256     EXPECT_TRUE(young_gc_duration->IsNull());
257     EXPECT_TRUE(young_gc_duration_delta->IsNull());
258   }
259 }
260 
261 class ZygoteHeapTest : public CommonRuntimeTest {
262  public:
ZygoteHeapTest()263   ZygoteHeapTest() {
264     use_boot_image_ = true;  // Make the Runtime creation cheaper.
265   }
266 
SetUpRuntimeOptions(RuntimeOptions * options)267   void SetUpRuntimeOptions(RuntimeOptions* options) override {
268     CommonRuntimeTest::SetUpRuntimeOptions(options);
269     options->push_back(std::make_pair("-Xzygote", nullptr));
270   }
271 };
272 
TEST_F(ZygoteHeapTest,PreZygoteFork)273 TEST_F(ZygoteHeapTest, PreZygoteFork) {
274   // Exercise Heap::PreZygoteFork() to check it does not crash.
275   Runtime::Current()->GetHeap()->PreZygoteFork();
276 }
277 
278 }  // namespace gc
279 }  // namespace art
280