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