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