summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Kuznetsov <[email protected]>2024-11-15 11:53:04 +0100
committerGitHub <[email protected]>2024-11-15 11:53:04 +0100
commit87530bec573db47883cd74df34899e3c2ab1705f (patch)
tree1a8ec8ad45bcfcdeefadb441c9caacffb45f5126
parent64458bf40ba22f6c4ecc27e1343161fe2429a95c (diff)
Add new UT for IC memory consumption (#11546)
-rw-r--r--ydb/library/actors/core/events.h4
-rw-r--r--ydb/library/actors/interconnect/event_holder_pool.h8
-rw-r--r--ydb/library/actors/interconnect/ut/event_holder_pool_ut.cpp65
3 files changed, 72 insertions, 5 deletions
diff --git a/ydb/library/actors/core/events.h b/ydb/library/actors/core/events.h
index 115b09424f2..341d76ffcdd 100644
--- a/ydb/library/actors/core/events.h
+++ b/ydb/library/actors/core/events.h
@@ -71,6 +71,10 @@ namespace NActors {
return serializer->WriteString(&Blob);
}
+ virtual ui32 CalculateSerializedSize() const override {
+ return Blob.size();
+ }
+
static IEventBase* Load(TEventSerializedData* bufs) noexcept {
return new TEvBlob(bufs->GetString());
}
diff --git a/ydb/library/actors/interconnect/event_holder_pool.h b/ydb/library/actors/interconnect/event_holder_pool.h
index d95a14402f4..5c9ca6187a6 100644
--- a/ydb/library/actors/interconnect/event_holder_pool.h
+++ b/ydb/library/actors/interconnect/event_holder_pool.h
@@ -37,16 +37,16 @@ namespace NActors {
class TEventHolderPool {
using TDestroyCallback = std::function<void(THolder<IEventBase>)>;
- static constexpr size_t MaxFreeQueueItems = 32;
- static constexpr size_t FreeQueueTrimThreshold = MaxFreeQueueItems * 2;
- static constexpr ui64 MaxBytesPerMessage = 10 * 1024 * 1024;
-
TIntrusivePtr<TInterconnectProxyCommon> Common;
std::list<TEventHolder> Cache;
THolder<TEvFreeItems> PendingFreeEvent;
TDestroyCallback DestroyCallback;
public:
+ static constexpr size_t MaxFreeQueueItems = 32;
+ static constexpr size_t FreeQueueTrimThreshold = MaxFreeQueueItems * 2;
+ static constexpr ui64 MaxBytesPerMessage = 10 * 1024 * 1024;
+
TEventHolderPool(TIntrusivePtr<TInterconnectProxyCommon> common,
TDestroyCallback destroyCallback)
: Common(std::move(common))
diff --git a/ydb/library/actors/interconnect/ut/event_holder_pool_ut.cpp b/ydb/library/actors/interconnect/ut/event_holder_pool_ut.cpp
index 2395051b78d..b489dd5723e 100644
--- a/ydb/library/actors/interconnect/ut/event_holder_pool_ut.cpp
+++ b/ydb/library/actors/interconnect/ut/event_holder_pool_ut.cpp
@@ -1,10 +1,13 @@
+#include <library/cpp/malloc/api/malloc.h>
+#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/library/actors/core/events.h>
#include <ydb/library/actors/core/event_local.h>
#include <ydb/library/actors/interconnect/interconnect_common.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <ydb/library/actors/interconnect/event_holder_pool.h>
+#include <contrib/libs/tcmalloc/tcmalloc/malloc_extension.h>
+
#include <atomic>
using namespace NActors;
@@ -56,4 +59,64 @@ Y_UNIT_TEST_SUITE(EventHolderPool) {
freeQ.clear(); // if we don't this, we may probablty crash due to the order of object destruction
}
+ struct TMemProfiler {
+ size_t UsedAtStart = 0;
+
+
+ TMemProfiler()
+ : UsedAtStart(0)
+ {
+ UsedAtStart = GetUsed();
+
+ const auto &info = NMalloc::MallocInfo();
+ bool tcmallocIsUsed = TStringBuf(info.Name).StartsWith("tc");
+ UNIT_ASSERT(tcmallocIsUsed);
+ }
+
+ size_t GetUsed() {
+ auto properties = tcmalloc::MallocExtension::GetProperties();
+ auto x = properties["generic.bytes_in_use_by_app"];
+ return x.value - UsedAtStart;
+ }
+ };
+
+ void MemComsumption(size_t repeats, size_t buffSize) {
+ TDeque<THolder<IEventBase>> freeQ;
+ auto callback = [&](THolder<IEventBase> event) {
+ freeQ.push_back(std::move(event));
+ };
+ auto pool = Setup(std::move(callback));
+
+ std::list<TEventHolder> q;
+ TMemProfiler prof;
+
+ for (ui32 i = 0; i < repeats; i++) {
+ TEventHolder& event = pool.Allocate(q);
+ TString data = TString::Uninitialized(buffSize);
+ auto holder = MakeHolder<IEventHandle>(TActorId{}, TActorId{}, new TEvents::TEvBlob(data));
+ event.Fill(*holder);
+
+ pool.Release(q, q.begin());
+ UNIT_ASSERT_LT_C(prof.GetUsed(), TEventHolderPool::MaxBytesPerMessage * 2, prof.GetUsed());
+ }
+
+ for (ui32 i = 0; i < repeats; i++) {
+ TEventHolder& event = pool.Allocate(q);
+ TString data = TString::Uninitialized(buffSize);
+ auto holder = MakeHolder<IEventHandle>(TActorId{}, TActorId{}, new TEvents::TEvBlob(data));
+ event.Fill(*holder);
+ }
+ for (ui32 i = 0; i < repeats; i++) {
+ pool.Release(q, q.begin());
+ }
+ UNIT_ASSERT_LT_C(prof.GetUsed(), TEventHolderPool::MaxBytesPerMessage * 2, prof.GetUsed());
+ }
+
+ Y_UNIT_TEST(MemConsumptionSmall) {
+ MemComsumption(100'000, 4);
+ }
+
+ Y_UNIT_TEST(MemConsumptionLarge) {
+ MemComsumption(10'000, 1024*1024);
+ }
}