diff options
| author | Vlad Kuznetsov <[email protected]> | 2024-11-15 11:53:04 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-11-15 11:53:04 +0100 |
| commit | 87530bec573db47883cd74df34899e3c2ab1705f (patch) | |
| tree | 1a8ec8ad45bcfcdeefadb441c9caacffb45f5126 | |
| parent | 64458bf40ba22f6c4ecc27e1343161fe2429a95c (diff) | |
Add new UT for IC memory consumption (#11546)
| -rw-r--r-- | ydb/library/actors/core/events.h | 4 | ||||
| -rw-r--r-- | ydb/library/actors/interconnect/event_holder_pool.h | 8 | ||||
| -rw-r--r-- | ydb/library/actors/interconnect/ut/event_holder_pool_ut.cpp | 65 |
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); + } } |
