%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/memory-balancer.h |
// Copyright 2023 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_HEAP_MEMORY_BALANCER_H_ #define V8_HEAP_MEMORY_BALANCER_H_ #include "src/base/platform/time.h" #include "src/tasks/cancelable-task.h" namespace v8 { namespace internal { class Heap; // The class that implements memory balancing. // Listen to allocation/garbage collection events // and smooth them using an exponentially weighted moving average (EWMA). // Spawn a heartbeat task that monitors allocation rate. // Calculate heap limit and update it accordingly. class MemoryBalancer { public: MemoryBalancer(Heap* heap, base::TimeTicks startup_time); void UpdateAllocationRate(size_t major_allocation_bytes, base::TimeDelta major_allocation_duration); void UpdateGCSpeed(size_t major_gc_bytes, base::TimeDelta major_gc_duration); void HeartbeatUpdate(); void RecomputeLimits(size_t embedder_allocation_limit, base::TimeTicks time); private: class SmoothedBytesAndDuration { public: SmoothedBytesAndDuration(size_t bytes, double duration) : bytes_(static_cast<double>(bytes)), duration_(duration) {} void Update(size_t bytes, double duration, double decay_rate) { bytes_ = bytes_ * decay_rate + static_cast<double>(bytes) * (1 - decay_rate); duration_ = duration_ * decay_rate + duration * (1 - decay_rate); } // Return memory (in bytes) over time (in millis). double rate() const { return bytes_ / duration_; } private: double bytes_; double duration_; }; static constexpr double kMajorAllocationDecayRate = 0.95; static constexpr double kMajorGCDecayRate = 0.5; void RefreshLimit(); void PostHeartbeatTask(); Heap* heap_; // Live memory estimate of the heap, obtained at the last major garbage // collection. size_t live_memory_after_gc_ = 0; // We want to set the old_generation_allocation_limit our way, // but when we do so we are taking memory from the external heap, // because the global allocation limit is shared between old generation and // external heap. We thus calculate the external heap limit and keep it // unchanged, by 'patching' the global_allocation_limit_. // A more principled solution is to also manage the external heapusing // membalancer. We can also replace global_allocation_limit_ in heap.cc with // external_allocation_limit_. Then we can recover global_allocation_limit_ // via old_generation_allocation_limit_ + external_allocation_limit_. size_t embedder_allocation_limit_ = 0; // Our estimate of major allocation rate and major GC speed. base::Optional<SmoothedBytesAndDuration> major_allocation_rate_; base::Optional<SmoothedBytesAndDuration> major_gc_speed_; // HeartbeatTask uses the diff between last observed time/memory and // current time/memory to calculate the allocation rate. size_t last_measured_memory_ = 0; base::TimeTicks last_measured_at_; bool heartbeat_task_started_ = false; }; class HeartbeatTask : public CancelableTask { public: explicit HeartbeatTask(Isolate* isolate, MemoryBalancer* mb); ~HeartbeatTask() override = default; HeartbeatTask(const HeartbeatTask&) = delete; HeartbeatTask& operator=(const HeartbeatTask&) = delete; private: // v8::internal::CancelableTask overrides. void RunInternal() override; MemoryBalancer* mb_; }; } // namespace internal } // namespace v8 #endif // V8_HEAP_MEMORY_BALANCER_H_