garbage_collector.h revision 3130cdf29eb203be0c38d1107a65d920ec39c106
12b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier/*
22b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * Copyright (C) 2012 The Android Open Source Project
32b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier *
42b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License");
52b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * you may not use this file except in compliance with the License.
62b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * You may obtain a copy of the License at
72b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier *
82b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier *      http://www.apache.org/licenses/LICENSE-2.0
92b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier *
102b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * Unless required by applicable law or agreed to in writing, software
112b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS,
122b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * See the License for the specific language governing permissions and
142b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier * limitations under the License.
152b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier */
162b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
192b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier
20b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier#include "base/histogram.h"
21719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h"
22b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier#include "base/timing_logger.h"
233e41780cb3bcade3b724908e00443a9caf6977efHiroshi Yamauchi#include "gc/collector_type.h"
246f4ffe41649f1e6381e8cda087ad3749206806e5Hiroshi Yamauchi#include "gc/gc_cause.h"
25bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier#include "gc_root.h"
261d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc_type.h"
272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <stdint.h>
282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <vector>
292b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier
302b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartiernamespace art {
311d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc {
322b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier
332b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartierclass Heap;
342b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier
351d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace collector {
361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartierstruct ObjectBytePair {
3810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  ObjectBytePair(uint64_t num_objects = 0, int64_t num_bytes = 0)
3910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier      : objects(num_objects), bytes(num_bytes) {}
4010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  void Add(const ObjectBytePair& other) {
4110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    objects += other.objects;
4210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    bytes += other.bytes;
4310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
4410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Number of objects which were freed.
4510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  uint64_t objects;
4610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Freed bytes are signed since the GC can free negative bytes if it promotes objects to a space
4710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // which has a larger allocation size.
4810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  int64_t bytes;
4910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier};
5010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier
5110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier// A information related single garbage collector iteration. Since we only ever have one GC running
5210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier// at any given time, we can have a single iteration info.
5310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartierclass Iteration {
5410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier public:
5510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  Iteration();
5610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Returns how long the mutators were paused in nanoseconds.
5710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  const std::vector<uint64_t>& GetPauseTimes() const {
5810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return pause_times_;
5910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
6010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  TimingLogger* GetTimings() {
6110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return &timings_;
6210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
6310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Returns how long the GC took to complete in nanoseconds.
6410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  uint64_t GetDurationNs() const {
6510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return duration_ns_;
6610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
6710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  int64_t GetFreedBytes() const {
6810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return freed_.bytes;
6910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
7010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  int64_t GetFreedLargeObjectBytes() const {
7110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return freed_los_.bytes;
7210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
7310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  uint64_t GetFreedObjects() const {
7410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return freed_.objects;
7510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
7610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  uint64_t GetFreedLargeObjects() const {
7710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return freed_los_.objects;
7810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
794460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  uint64_t GetFreedRevokeBytes() const {
804460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi    return freed_bytes_revoke_;
814460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  }
824460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  void SetFreedRevoke(uint64_t freed) {
834460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi    freed_bytes_revoke_ = freed;
844460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  }
8510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  void Reset(GcCause gc_cause, bool clear_soft_references);
8610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Returns the estimated throughput of the iteration.
8710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  uint64_t GetEstimatedThroughput() const;
8810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  bool GetClearSoftReferences() const {
8910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return clear_soft_references_;
9010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
9110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  void SetClearSoftReferences(bool clear_soft_references) {
9210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    clear_soft_references_ = clear_soft_references;
9310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
9410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  GcCause GetGcCause() const {
9510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return gc_cause_;
9610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
9710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier
9810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier private:
9910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  void SetDurationNs(uint64_t duration) {
10010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    duration_ns_ = duration;
10110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
10210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier
10310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  GcCause gc_cause_;
10410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  bool clear_soft_references_;
10510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  uint64_t duration_ns_;
10610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  TimingLogger timings_;
10710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  ObjectBytePair freed_;
10810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  ObjectBytePair freed_los_;
1094460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  uint64_t freed_bytes_revoke_;  // see Heap::num_bytes_freed_revoke_.
11010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  std::vector<uint64_t> pause_times_;
11110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier
11210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  friend class GarbageCollector;
11310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  DISALLOW_COPY_AND_ASSIGN(Iteration);
11410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier};
11510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier
116bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass GarbageCollector : public RootVisitor {
1172b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier public:
1186f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  class SCOPED_LOCKABLE ScopedPause {
1196f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier   public:
1206f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier    explicit ScopedPause(GarbageCollector* collector) EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_);
1216f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier    ~ScopedPause() UNLOCK_FUNCTION();
1226f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier
1236f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier   private:
1246f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier    const uint64_t start_time_;
1256f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier    GarbageCollector* const collector_;
1266f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  };
1276f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier
1281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  GarbageCollector(Heap* heap, const std::string& name);
1291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~GarbageCollector() { }
1301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  const char* GetName() const {
1311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return name_.c_str();
1321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual GcType GetGcType() const = 0;
1343e41780cb3bcade3b724908e00443a9caf6977efHiroshi Yamauchi  virtual CollectorType GetCollectorType() const = 0;
1352b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier  // Run the garbage collector.
1366f4ffe41649f1e6381e8cda087ad3749206806e5Hiroshi Yamauchi  void Run(GcCause gc_cause, bool clear_soft_references);
1371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  Heap* GetHeap() const {
1382b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier    return heap_;
1392b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier  }
1401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  void RegisterPause(uint64_t nano_length);
141afe4998fc15b8de093d6b282c9782d7182829e36Mathieu Chartier  const CumulativeLogger& GetCumulativeTimings() const {
1421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return cumulative_timings_;
1431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  void ResetCumulativeStatistics();
1451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Swap the live and mark bitmaps of spaces that are active for the collector. For partial GC,
1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // this is the allocation space, for full GC then we swap the zygote bitmaps too.
1471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  void SwapBitmaps() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
148104fa0c0c7dad925d9f4d5c101a8064cd6830da7Mathieu Chartier  uint64_t GetTotalPausedTimeNs() LOCKS_EXCLUDED(pause_histogram_lock_);
149e76e70f424468f311c2061c291e8384263f3968cMathieu Chartier  int64_t GetTotalFreedBytes() const {
150590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return total_freed_bytes_;
151590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
152590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  uint64_t GetTotalFreedObjects() const {
153590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return total_freed_objects_;
154590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
1555a48719b516a52d1a6800d8ae6f7dcba3d883bdcMathieu Chartier  // Reset the cumulative timings and pause histogram.
1565a48719b516a52d1a6800d8ae6f7dcba3d883bdcMathieu Chartier  void ResetMeasurements();
157afe4998fc15b8de093d6b282c9782d7182829e36Mathieu Chartier  // Returns the estimated throughput in bytes / second.
158afe4998fc15b8de093d6b282c9782d7182829e36Mathieu Chartier  uint64_t GetEstimatedMeanThroughput() const;
159afe4998fc15b8de093d6b282c9782d7182829e36Mathieu Chartier  // Returns how many GC iterations have been run.
16010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  size_t NumberOfIterations() const {
161afe4998fc15b8de093d6b282c9782d7182829e36Mathieu Chartier    return GetCumulativeTimings().GetIterations();
162afe4998fc15b8de093d6b282c9782d7182829e36Mathieu Chartier  }
16310fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Returns the current GC iteration and assocated info.
16410fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  Iteration* GetCurrentIteration();
16510fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  const Iteration* GetCurrentIteration() const;
16610fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  TimingLogger* GetTimings() {
16710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier    return &GetCurrentIteration()->timings_;
16810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  }
16910fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Record a free of normal objects.
17010fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  void RecordFree(const ObjectBytePair& freed);
17110fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  // Record a free of large objects.
17210fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier  void RecordFreeLOS(const ObjectBytePair& freed);
173104fa0c0c7dad925d9f4d5c101a8064cd6830da7Mathieu Chartier  void DumpPerformanceInfo(std::ostream& os) LOCKS_EXCLUDED(pause_histogram_lock_);
174afe4998fc15b8de093d6b282c9782d7182829e36Mathieu Chartier
1752b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier protected:
1766f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  // Run all of the GC phases.
1776f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier  virtual void RunPhases() = 0;
178c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi  // Revoke all the thread-local buffers.
179c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi  virtual void RevokeAllThreadLocalBuffers() = 0;
180d6534315596326f1a65aa2d300144c09205c5122Mathieu Chartier
181b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier  static constexpr size_t kPauseBucketSize = 500;
182b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier  static constexpr size_t kPauseBucketCount = 32;
183b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier
1841d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  Heap* const heap_;
1851d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  std::string name_;
1861d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Cumulative statistics.
187104fa0c0c7dad925d9f4d5c101a8064cd6830da7Mathieu Chartier  Histogram<uint64_t> pause_histogram_ GUARDED_BY(pause_histogram_lock_);
1881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  uint64_t total_time_ns_;
1891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  uint64_t total_freed_objects_;
190e76e70f424468f311c2061c291e8384263f3968cMathieu Chartier  int64_t total_freed_bytes_;
1911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  CumulativeLogger cumulative_timings_;
192104fa0c0c7dad925d9f4d5c101a8064cd6830da7Mathieu Chartier  mutable Mutex pause_histogram_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
1933130cdf29eb203be0c38d1107a65d920ec39c106Mathieu Chartier
1943130cdf29eb203be0c38d1107a65d920ec39c106Mathieu Chartier private:
1953130cdf29eb203be0c38d1107a65d920ec39c106Mathieu Chartier  DISALLOW_IMPLICIT_CONSTRUCTORS(GarbageCollector);
1962b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier};
1972b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier
1981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace collector
1991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
2002b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier}  // namespace art
2012b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier
202fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
203