Skip to content

Commit 3bc6156

Browse files
tsaarniphlax
authored andcommitted
Use allocated memory for fixed heap pressure (#41442)
After applying this PR the fixed heap resource monitor will use allocated memory for memory pressure calculation, so reported pressure is lower and more accurate. This can prevent unnecessary load shedding when there is enough free memory. New formula is simply: `currently_allocated / max_heap_size` and it does not include any overhead that allocations might have. See #21923 (comment) for background. **Risk Level:** Low **Testing:** test case added **Docs Changes:** **Release Notes:** **Runtime guard:** `envoy.reloadable_features.fixed_heap_use_allocated`. Default value is `false`. Fixes #21923 --------- Signed-off-by: Tero Saarni <[email protected]> Signed-off-by: Tero Saarni <[email protected]>
1 parent e801a8b commit 3bc6156

File tree

6 files changed

+60
-4
lines changed

6 files changed

+60
-4
lines changed

changelogs/current.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,12 @@ removed_config_or_runtime:
1818
# *Normally occurs at the end of the* :ref:`deprecation period <deprecated>`
1919

2020
new_features:
21+
- area: overload management
22+
change: |
23+
The fixed heap resource monitor can now calculate memory pressure as currently allocated memory divided by maximum heap size,
24+
giving more accurate and lower memory pressure values.
25+
This can avoid unnecessary load shedding or overload actions.
26+
To enable, set ``envoy.reloadable_features.fixed_heap_use_allocated`` to true.
27+
The default algorithm (heap_size - pageheap_unmapped - pageheap_free) does not discount for free memory in TCMalloc caches.
2128
2229
deprecated:

source/common/runtime/runtime_features.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ FALSE_RUNTIME_GUARD(envoy_restart_features_use_cached_grpc_client_for_xds);
190190
// Runtime guard to revert back to old non-RFC-compliant CONNECT behavior without Host header.
191191
// TODO(vinaykul): Drop this false-runtime-guard when deemed safe with RFC 9110 compliant CONNECT.
192192
FALSE_RUNTIME_GUARD(envoy_reloadable_features_http_11_proxy_connect_legacy_format);
193+
// TODO(tsaarni): Flip to true after prod testing or remove.
194+
FALSE_RUNTIME_GUARD(envoy_reloadable_features_fixed_heap_use_allocated);
193195

194196
// Block of non-boolean flags. Use of int flags is deprecated. Do not add more.
195197
ABSL_FLAG(uint64_t, re2_max_program_size_error_level, 100, ""); // NOLINT

source/extensions/resource_monitors/fixed_heap/fixed_heap_monitor.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "source/common/common/assert.h"
66
#include "source/common/memory/stats.h"
7+
#include "source/common/runtime/runtime_features.h"
78

89
namespace Envoy {
910
namespace Extensions {
@@ -16,6 +17,10 @@ uint64_t MemoryStatsReader::unmappedHeapBytes() { return Memory::Stats::totalPag
1617

1718
uint64_t MemoryStatsReader::freeMappedHeapBytes() { return Memory::Stats::totalPageHeapFree(); }
1819

20+
uint64_t MemoryStatsReader::allocatedHeapBytes() {
21+
return Memory::Stats::totalCurrentlyAllocated();
22+
}
23+
1924
FixedHeapMonitor::FixedHeapMonitor(
2025
const envoy::extensions::resource_monitors::fixed_heap::v3::FixedHeapConfig& config,
2126
std::unique_ptr<MemoryStatsReader> stats)
@@ -25,16 +30,17 @@ FixedHeapMonitor::FixedHeapMonitor(
2530

2631
void FixedHeapMonitor::updateResourceUsage(Server::ResourceUpdateCallbacks& callbacks) {
2732

28-
auto computeUsedMemory = [this]() -> size_t {
33+
size_t used = 0;
34+
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.fixed_heap_use_allocated")) {
35+
used = stats_->allocatedHeapBytes();
36+
} else {
2937
const size_t physical = stats_->reservedHeapBytes();
3038
const size_t unmapped = stats_->unmappedHeapBytes();
3139
const size_t free_mapped = stats_->freeMappedHeapBytes();
3240
ASSERT(physical >= (unmapped + free_mapped));
33-
return physical - unmapped - free_mapped;
41+
used = physical - unmapped - free_mapped;
3442
};
3543

36-
const size_t used = computeUsedMemory();
37-
3844
Server::ResourceUsage usage;
3945
usage.resource_pressure_ = used / static_cast<double>(max_heap_);
4046

source/extensions/resource_monitors/fixed_heap/fixed_heap_monitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class MemoryStatsReader {
2222
virtual uint64_t unmappedHeapBytes();
2323
// Memory in free, mapped pages in the page heap.
2424
virtual uint64_t freeMappedHeapBytes();
25+
// Memory currently allocated by the process.
26+
virtual uint64_t allocatedHeapBytes();
2527
};
2628

2729
/**

test/extensions/resource_monitors/fixed_heap/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ envoy_extension_cc_test(
1818
rbe_pool = "6gig",
1919
deps = [
2020
"//source/extensions/resource_monitors/fixed_heap:fixed_heap_monitor",
21+
"//test/test_common:test_runtime_lib",
2122
"@com_google_absl//absl/types:optional",
2223
"@envoy_api//envoy/extensions/resource_monitors/fixed_heap/v3:pkg_cc_proto",
2324
],

test/extensions/resource_monitors/fixed_heap/fixed_heap_monitor_test.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "source/extensions/resource_monitors/fixed_heap/fixed_heap_monitor.h"
44

5+
#include "test/test_common/test_runtime.h"
6+
57
#include "absl/types/optional.h"
68
#include "gmock/gmock.h"
79
#include "gtest/gtest.h"
@@ -21,6 +23,7 @@ class MockMemoryStatsReader : public MemoryStatsReader {
2123
MOCK_METHOD(uint64_t, reservedHeapBytes, ());
2224
MOCK_METHOD(uint64_t, unmappedHeapBytes, ());
2325
MOCK_METHOD(uint64_t, freeMappedHeapBytes, ());
26+
MOCK_METHOD(uint64_t, allocatedHeapBytes, ());
2427
};
2528

2629
class ResourcePressure : public Server::ResourceUpdateCallbacks {
@@ -58,6 +61,23 @@ TEST(FixedHeapMonitorTest, ComputesCorrectUsage) {
5861
EXPECT_EQ(resource.pressure(), 0.5);
5962
}
6063

64+
TEST(FixedHeapMonitorTest, ComputesCorrectUsageRuntimeUseAllocated) {
65+
TestScopedRuntime scoped_runtime;
66+
scoped_runtime.mergeValues({{"envoy.reloadable_features.fixed_heap_use_allocated", "true"}});
67+
68+
envoy::extensions::resource_monitors::fixed_heap::v3::FixedHeapConfig config;
69+
config.set_max_heap_size_bytes(1000);
70+
auto stats_reader = std::make_unique<MockMemoryStatsReader>();
71+
EXPECT_CALL(*stats_reader, allocatedHeapBytes()).WillOnce(Return(600));
72+
auto monitor = std::make_unique<FixedHeapMonitor>(config, std::move(stats_reader));
73+
74+
ResourcePressure resource;
75+
monitor->updateResourceUsage(resource);
76+
ASSERT_TRUE(resource.hasPressure());
77+
ASSERT_FALSE(resource.hasError());
78+
EXPECT_EQ(resource.pressure(), 0.6);
79+
}
80+
6181
TEST(FixedHeapMonitorTest, ComputeUsageWithRealMemoryStats) {
6282

6383
envoy::extensions::resource_monitors::fixed_heap::v3::FixedHeapConfig config;
@@ -74,6 +94,24 @@ TEST(FixedHeapMonitorTest, ComputeUsageWithRealMemoryStats) {
7494
monitor->updateResourceUsage(resource);
7595
EXPECT_NEAR(resource.pressure(), expected_usage, 0.0005);
7696
}
97+
98+
TEST(FixedHeapMonitorTest, ComputesUsageRuntimeUseAllocatedWithRealMemoryStats) {
99+
TestScopedRuntime scoped_runtime;
100+
scoped_runtime.mergeValues({{"envoy.reloadable_features.fixed_heap_use_allocated", "true"}});
101+
102+
envoy::extensions::resource_monitors::fixed_heap::v3::FixedHeapConfig config;
103+
const uint64_t max_heap = 1024 * 1024 * 1024;
104+
config.set_max_heap_size_bytes(max_heap);
105+
auto stats_reader = std::make_unique<MemoryStatsReader>();
106+
const double expected_pressure =
107+
stats_reader->allocatedHeapBytes() / static_cast<double>(max_heap);
108+
auto monitor = std::make_unique<FixedHeapMonitor>(config, std::move(stats_reader));
109+
110+
ResourcePressure resource;
111+
monitor->updateResourceUsage(resource);
112+
EXPECT_NEAR(resource.pressure(), expected_pressure, 0.0005);
113+
}
114+
77115
} // namespace
78116
} // namespace FixedHeapMonitor
79117
} // namespace ResourceMonitors

0 commit comments

Comments
 (0)