1 /*
2  * Copyright (C) 2012 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 #ifndef ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
18 #define ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
19 
20 #include "base/histogram.h"
21 #include "base/mutex.h"
22 #include "base/timing_logger.h"
23 #include "gc/collector_type.h"
24 #include "gc/gc_cause.h"
25 #include "gc_root.h"
26 #include "gc_type.h"
27 #include <stdint.h>
28 #include <vector>
29 
30 namespace art {
31 namespace gc {
32 
33 class Heap;
34 
35 namespace collector {
36 
37 struct ObjectBytePair {
38   ObjectBytePair(uint64_t num_objects = 0, int64_t num_bytes = 0)
objectsObjectBytePair39       : objects(num_objects), bytes(num_bytes) {}
AddObjectBytePair40   void Add(const ObjectBytePair& other) {
41     objects += other.objects;
42     bytes += other.bytes;
43   }
44   // Number of objects which were freed.
45   uint64_t objects;
46   // Freed bytes are signed since the GC can free negative bytes if it promotes objects to a space
47   // which has a larger allocation size.
48   int64_t bytes;
49 };
50 
51 // A information related single garbage collector iteration. Since we only ever have one GC running
52 // at any given time, we can have a single iteration info.
53 class Iteration {
54  public:
55   Iteration();
56   // Returns how long the mutators were paused in nanoseconds.
GetPauseTimes()57   const std::vector<uint64_t>& GetPauseTimes() const {
58     return pause_times_;
59   }
GetTimings()60   TimingLogger* GetTimings() {
61     return &timings_;
62   }
63   // Returns how long the GC took to complete in nanoseconds.
GetDurationNs()64   uint64_t GetDurationNs() const {
65     return duration_ns_;
66   }
GetFreedBytes()67   int64_t GetFreedBytes() const {
68     return freed_.bytes;
69   }
GetFreedLargeObjectBytes()70   int64_t GetFreedLargeObjectBytes() const {
71     return freed_los_.bytes;
72   }
GetFreedObjects()73   uint64_t GetFreedObjects() const {
74     return freed_.objects;
75   }
GetFreedLargeObjects()76   uint64_t GetFreedLargeObjects() const {
77     return freed_los_.objects;
78   }
GetFreedRevokeBytes()79   uint64_t GetFreedRevokeBytes() const {
80     return freed_bytes_revoke_;
81   }
SetFreedRevoke(uint64_t freed)82   void SetFreedRevoke(uint64_t freed) {
83     freed_bytes_revoke_ = freed;
84   }
85   void Reset(GcCause gc_cause, bool clear_soft_references);
86   // Returns the estimated throughput of the iteration.
87   uint64_t GetEstimatedThroughput() const;
GetClearSoftReferences()88   bool GetClearSoftReferences() const {
89     return clear_soft_references_;
90   }
SetClearSoftReferences(bool clear_soft_references)91   void SetClearSoftReferences(bool clear_soft_references) {
92     clear_soft_references_ = clear_soft_references;
93   }
GetGcCause()94   GcCause GetGcCause() const {
95     return gc_cause_;
96   }
97 
98  private:
SetDurationNs(uint64_t duration)99   void SetDurationNs(uint64_t duration) {
100     duration_ns_ = duration;
101   }
102 
103   GcCause gc_cause_;
104   bool clear_soft_references_;
105   uint64_t duration_ns_;
106   TimingLogger timings_;
107   ObjectBytePair freed_;
108   ObjectBytePair freed_los_;
109   uint64_t freed_bytes_revoke_;  // see Heap::num_bytes_freed_revoke_.
110   std::vector<uint64_t> pause_times_;
111 
112   friend class GarbageCollector;
113   DISALLOW_COPY_AND_ASSIGN(Iteration);
114 };
115 
116 class GarbageCollector : public RootVisitor {
117  public:
118   class SCOPED_LOCKABLE ScopedPause {
119    public:
120     explicit ScopedPause(GarbageCollector* collector) EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_);
121     ~ScopedPause() UNLOCK_FUNCTION();
122 
123    private:
124     const uint64_t start_time_;
125     GarbageCollector* const collector_;
126   };
127 
128   GarbageCollector(Heap* heap, const std::string& name);
~GarbageCollector()129   virtual ~GarbageCollector() { }
GetName()130   const char* GetName() const {
131     return name_.c_str();
132   }
133   virtual GcType GetGcType() const = 0;
134   virtual CollectorType GetCollectorType() const = 0;
135   // Run the garbage collector.
136   void Run(GcCause gc_cause, bool clear_soft_references);
GetHeap()137   Heap* GetHeap() const {
138     return heap_;
139   }
140   void RegisterPause(uint64_t nano_length);
GetCumulativeTimings()141   const CumulativeLogger& GetCumulativeTimings() const {
142     return cumulative_timings_;
143   }
144   void ResetCumulativeStatistics();
145   // Swap the live and mark bitmaps of spaces that are active for the collector. For partial GC,
146   // this is the allocation space, for full GC then we swap the zygote bitmaps too.
147   void SwapBitmaps() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
148   uint64_t GetTotalPausedTimeNs() LOCKS_EXCLUDED(pause_histogram_lock_);
GetTotalFreedBytes()149   int64_t GetTotalFreedBytes() const {
150     return total_freed_bytes_;
151   }
GetTotalFreedObjects()152   uint64_t GetTotalFreedObjects() const {
153     return total_freed_objects_;
154   }
155   // Reset the cumulative timings and pause histogram.
156   void ResetMeasurements();
157   // Returns the estimated throughput in bytes / second.
158   uint64_t GetEstimatedMeanThroughput() const;
159   // Returns how many GC iterations have been run.
NumberOfIterations()160   size_t NumberOfIterations() const {
161     return GetCumulativeTimings().GetIterations();
162   }
163   // Returns the current GC iteration and assocated info.
164   Iteration* GetCurrentIteration();
165   const Iteration* GetCurrentIteration() const;
GetTimings()166   TimingLogger* GetTimings() {
167     return &GetCurrentIteration()->timings_;
168   }
169   // Record a free of normal objects.
170   void RecordFree(const ObjectBytePair& freed);
171   // Record a free of large objects.
172   void RecordFreeLOS(const ObjectBytePair& freed);
173   void DumpPerformanceInfo(std::ostream& os) LOCKS_EXCLUDED(pause_histogram_lock_);
174 
175  protected:
176   // Run all of the GC phases.
177   virtual void RunPhases() = 0;
178   // Revoke all the thread-local buffers.
179   virtual void RevokeAllThreadLocalBuffers() = 0;
180 
181   static constexpr size_t kPauseBucketSize = 500;
182   static constexpr size_t kPauseBucketCount = 32;
183 
184   Heap* const heap_;
185   std::string name_;
186   // Cumulative statistics.
187   Histogram<uint64_t> pause_histogram_ GUARDED_BY(pause_histogram_lock_);
188   uint64_t total_time_ns_;
189   uint64_t total_freed_objects_;
190   int64_t total_freed_bytes_;
191   CumulativeLogger cumulative_timings_;
192   mutable Mutex pause_histogram_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
193 
194  private:
195   DISALLOW_IMPLICIT_CONSTRUCTORS(GarbageCollector);
196 };
197 
198 }  // namespace collector
199 }  // namespace gc
200 }  // namespace art
201 
202 #endif  // ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
203