v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
memory-balancer.h
Go to the documentation of this file.
1// Copyright 2023 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_HEAP_MEMORY_BALANCER_H_
6#define V8_HEAP_MEMORY_BALANCER_H_
7
8#include <optional>
9
12
13namespace v8 {
14namespace internal {
15
16class Heap;
17
18// The class that implements memory balancing.
19// Listen to allocation/garbage collection events
20// and smooth them using an exponentially weighted moving average (EWMA).
21// Spawn a heartbeat task that monitors allocation rate.
22// Calculate heap limit and update it accordingly.
24 public:
26
27 void UpdateAllocationRate(size_t major_allocation_bytes,
28 base::TimeDelta major_allocation_duration);
29 void UpdateGCSpeed(size_t major_gc_bytes, base::TimeDelta major_gc_duration);
30
31 void HeartbeatUpdate();
32
33 void RecomputeLimits(size_t embedder_allocation_limit, base::TimeTicks time);
34
35 private:
37 public:
38 SmoothedBytesAndDuration(size_t bytes, double duration)
39 : bytes_(static_cast<double>(bytes)), duration_(duration) {}
40 void Update(size_t bytes, double duration, double decay_rate) {
41 bytes_ =
42 bytes_ * decay_rate + static_cast<double>(bytes) * (1 - decay_rate);
43 duration_ = duration_ * decay_rate + duration * (1 - decay_rate);
44 }
45 // Return memory (in bytes) over time (in millis).
46 double rate() const { return bytes_ / duration_; }
47
48 private:
49 double bytes_;
50 double duration_;
51 };
52
53 static constexpr double kMajorAllocationDecayRate = 0.95;
54 static constexpr double kMajorGCDecayRate = 0.5;
55
56 void RefreshLimit();
57 void PostHeartbeatTask();
58
60
61 // Live memory estimate of the heap, obtained at the last major garbage
62 // collection.
64
65 // We want to set the old_generation_allocation_limit our way,
66 // but when we do so we are taking memory from the external heap,
67 // because the global allocation limit is shared between old generation and
68 // external heap. We thus calculate the external heap limit and keep it
69 // unchanged, by 'patching' the global_allocation_limit_.
70 // A more principled solution is to also manage the external heapusing
71 // membalancer. We can also replace global_allocation_limit_ in heap.cc with
72 // external_allocation_limit_. Then we can recover global_allocation_limit_
73 // via old_generation_allocation_limit_ + external_allocation_limit_.
75
76 // Our estimate of major allocation rate and major GC speed.
77 std::optional<SmoothedBytesAndDuration> major_allocation_rate_;
78 std::optional<SmoothedBytesAndDuration> major_gc_speed_;
79
80 // HeartbeatTask uses the diff between last observed time/memory and
81 // current time/memory to calculate the allocation rate.
85};
86
88 public:
89 explicit HeartbeatTask(Isolate* isolate, MemoryBalancer* mb);
90
91 ~HeartbeatTask() override = default;
92 HeartbeatTask(const HeartbeatTask&) = delete;
94
95 private:
96 // v8::internal::CancelableTask overrides.
97 void RunInternal() override;
98
100};
101
102} // namespace internal
103} // namespace v8
104
105#endif // V8_HEAP_MEMORY_BALANCER_H_
HeartbeatTask & operator=(const HeartbeatTask &)=delete
~HeartbeatTask() override=default
HeartbeatTask(Isolate *isolate, MemoryBalancer *mb)
HeartbeatTask(const HeartbeatTask &)=delete
void Update(size_t bytes, double duration, double decay_rate)
MemoryBalancer(Heap *heap, base::TimeTicks startup_time)
std::optional< SmoothedBytesAndDuration > major_gc_speed_
static constexpr double kMajorAllocationDecayRate
void UpdateGCSpeed(size_t major_gc_bytes, base::TimeDelta major_gc_duration)
void RecomputeLimits(size_t embedder_allocation_limit, base::TimeTicks time)
void UpdateAllocationRate(size_t major_allocation_bytes, base::TimeDelta major_allocation_duration)
std::optional< SmoothedBytesAndDuration > major_allocation_rate_
static constexpr double kMajorGCDecayRate