garbage_collector.h revision d6534315596326f1a65aa2d300144c09205c5122
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" 236f4ffe41649f1e6381e8cda087ad3749206806e5Hiroshi Yamauchi#include "gc/gc_cause.h" 241d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc_type.h" 252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <stdint.h> 262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <vector> 272b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 282b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartiernamespace art { 291d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc { 302b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 312b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartierclass Heap; 322b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 331d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace collector { 341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 352b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartierclass GarbageCollector { 362b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier public: 372b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier // Returns true iff the garbage collector is concurrent. 382b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier virtual bool IsConcurrent() const = 0; 392b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers GarbageCollector(Heap* heap, const std::string& name); 411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers virtual ~GarbageCollector() { } 421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers const char* GetName() const { 441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return name_.c_str(); 451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 462b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers virtual GcType GetGcType() const = 0; 482b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 492b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier // Run the garbage collector. 506f4ffe41649f1e6381e8cda087ad3749206806e5Hiroshi Yamauchi void Run(GcCause gc_cause, bool clear_soft_references); 512b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers Heap* GetHeap() const { 532b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier return heap_; 542b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier } 552b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 562b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier // Returns how long the mutators were paused in nanoseconds. 572b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier const std::vector<uint64_t>& GetPauseTimes() const { 582b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier return pause_times_; 592b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier } 602b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 612b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier // Returns how long the GC took to complete in nanoseconds. 621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers uint64_t GetDurationNs() const { 631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return duration_ns_; 642b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier } 652b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers void RegisterPause(uint64_t nano_length); 671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 685fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers TimingLogger& GetTimings() { 691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return timings_; 701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 712b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers CumulativeLogger& GetCumulativeTimings() { 731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return cumulative_timings_; 741d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 752b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 761d54e73444e017d3a65234e0f193846f3e27472bIan Rogers void ResetCumulativeStatistics(); 771d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 781d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Swap the live and mark bitmaps of spaces that are active for the collector. For partial GC, 791d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // this is the allocation space, for full GC then we swap the zygote bitmaps too. 801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers void SwapBitmaps() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); 812b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 82590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t GetFreedBytes() const { 83590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return freed_bytes_; 84590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 85590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 86590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t GetFreedLargeObjectBytes() const { 87590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return freed_large_object_bytes_; 88590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 89590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 90590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t GetFreedObjects() const { 91590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return freed_objects_; 92590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 93590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 94590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t GetFreedLargeObjects() const { 95590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return freed_large_objects_; 96590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 97590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 98590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier uint64_t GetTotalPausedTimeNs() const { 99b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier return pause_histogram_.Sum(); 100590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 101590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 102590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier uint64_t GetTotalFreedBytes() const { 103590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return total_freed_bytes_; 104590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 105590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 106590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier uint64_t GetTotalFreedObjects() const { 107590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return total_freed_objects_; 108590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 109590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 110b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier const Histogram<uint64_t>& GetPauseHistogram() const { 111b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier return pause_histogram_; 112b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier } 113b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier 1142b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier protected: 1152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // The initial phase. Done without mutators paused. 1162b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier virtual void InitializePhase() = 0; 1172b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 1182b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier // Mark all reachable objects, done concurrently. 1192b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier virtual void MarkingPhase() = 0; 1202b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 1212b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier // Only called for concurrent GCs. Gets called repeatedly until it succeeds. 1222b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier virtual bool HandleDirtyObjectsPhase() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1232b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 1242b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier // Called with mutators running. 1252b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier virtual void ReclaimPhase() = 0; 1262b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Called after the GC is finished. Done without mutators paused. 1282b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier virtual void FinishPhase() = 0; 1292b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 130d6534315596326f1a65aa2d300144c09205c5122Mathieu Chartier void RevokeAllThreadLocalBuffers(); 131d6534315596326f1a65aa2d300144c09205c5122Mathieu Chartier 132b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier static constexpr size_t kPauseBucketSize = 500; 133b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier static constexpr size_t kPauseBucketCount = 32; 134b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier 1351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers Heap* const heap_; 1361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers std::string name_; 1381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1396f4ffe41649f1e6381e8cda087ad3749206806e5Hiroshi Yamauchi GcCause gc_cause_; 140590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier bool clear_soft_references_; 141590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 1421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers const bool verbose_; 1431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers uint64_t duration_ns_; 1455fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers TimingLogger timings_; 1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Cumulative statistics. 148b2f9936cab87a187f078187c22d9b29d4a188a62Mathieu Chartier Histogram<uint64_t> pause_histogram_; 1491d54e73444e017d3a65234e0f193846f3e27472bIan Rogers uint64_t total_time_ns_; 1501d54e73444e017d3a65234e0f193846f3e27472bIan Rogers uint64_t total_freed_objects_; 1511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers uint64_t total_freed_bytes_; 1521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 153590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier // Single GC statitstics. 154590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier AtomicInteger freed_bytes_; 155590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier AtomicInteger freed_large_object_bytes_; 156590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier AtomicInteger freed_objects_; 157590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier AtomicInteger freed_large_objects_; 158590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 1591d54e73444e017d3a65234e0f193846f3e27472bIan Rogers CumulativeLogger cumulative_timings_; 1601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1612b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier std::vector<uint64_t> pause_times_; 1622b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier}; 1632b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 1641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace collector 1651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace gc 1662b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier} // namespace art 1672b82db45c09450022199376c3a5420eacf2aa81eMathieu Chartier 168fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_ 169