Skip to content

Commit

Permalink
Add metrics to track initial memory capacity and growth
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoxmeng committed Apr 9, 2024
1 parent e29cde7 commit 6760fb6
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 9 deletions.
19 changes: 19 additions & 0 deletions velox/common/base/Counters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,25 @@ void registerVeloxMetrics() {
DEFINE_METRIC(
kMetricMemoryPoolReservationLeakBytes, facebook::velox::StatType::SUM);

// The distribution of a root memory pool's initial capacity in range of [0,
// 256MB] with 32 buckets. It is configured to report the capacity at P50, P90,
// P99, and P100 percentiles.
DEFINE_HISTOGRAM_METRIC(
kMetricMemoryPoolInitialCapacityBytes,
8L << 20,
0,
256L << 20,
50,
90,
99,
100);

// The distribution of a root memory pool cappacity growth attemps through
// memory arbitration in range of [0, 256] with 32 buckets. It is configured
// to report the count at P50, P90, P99, and P100 percentiles.
DEFINE_HISTOGRAM_METRIC(
kMetricMemoryPoolCapacityGrowCount, 8, 0, 256, 50, 90, 99, 100);

/// ================== Spill related Counters =================

// The number of bytes in memory to spill.
Expand Down
6 changes: 6 additions & 0 deletions velox/common/base/Counters.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ constexpr folly::StringPiece kMetricTaskMemoryReclaimWaitTimeoutCount{
constexpr folly::StringPiece kMetricMemoryNonReclaimableCount{
"velox.memory_non_reclaimable_count"};

constexpr folly::StringPiece kMetricMemoryPoolInitialCapacityBytes{
"velox.memory_pool_initial_capacity_bytes"};

constexpr folly::StringPiece kMetricMemoryPoolCapacityGrowCount{
"velox.memory_pool_capacity_growth_count"};

constexpr folly::StringPiece kMetricMemoryPoolUsageLeakBytes{
"velox.memory_pool_usage_leak_bytes"};

Expand Down
5 changes: 5 additions & 0 deletions velox/common/memory/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/

#include "velox/common/memory/Memory.h"

#include "velox/common/base/Counters.h"
#include "velox/common/base/StatsReporter.h"
#include "velox/common/memory/MallocAllocator.h"
#include "velox/common/memory/MmapAllocator.h"

Expand Down Expand Up @@ -207,6 +210,8 @@ std::shared_ptr<MemoryPool> MemoryManager::addRootPool(
VELOX_CHECK_EQ(pool->capacity(), 0);
arbitrator_->growCapacity(
pool.get(), std::min<uint64_t>(poolInitCapacity_, maxCapacity));
RECORD_HISTOGRAM_METRIC_VALUE(
kMetricMemoryPoolInitialCapacityBytes, pool->capacity());
return pool;
}

Expand Down
18 changes: 14 additions & 4 deletions velox/common/memory/MemoryPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ std::string capacityToString(int64_t capacity) {

std::string MemoryPool::Stats::toString() const {
return fmt::format(
"currentBytes:{} reservedBytes:{} peakBytes:{} cumulativeBytes:{} numAllocs:{} numFrees:{} numReserves:{} numReleases:{} numShrinks:{} numReclaims:{} numCollisions:{}",
"currentBytes:{} reservedBytes:{} peakBytes:{} cumulativeBytes:{} numAllocs:{} numFrees:{} numReserves:{} numReleases:{} numShrinks:{} numReclaims:{} numCollisions:{} numCapacityGrowths:{}",
succinctBytes(currentBytes),
succinctBytes(reservedBytes),
succinctBytes(peakBytes),
Expand All @@ -176,7 +176,8 @@ std::string MemoryPool::Stats::toString() const {
numReleases,
numShrinks,
numReclaims,
numCollisions);
numCollisions,
numCapacityGrowths);
}

bool MemoryPool::Stats::operator==(const MemoryPool::Stats& other) const {
Expand All @@ -189,7 +190,8 @@ bool MemoryPool::Stats::operator==(const MemoryPool::Stats& other) const {
numFrees,
numReserves,
numReleases,
numCollisions) ==
numCollisions,
numCapacityGrowths) ==
std::tie(
other.currentBytes,
other.reservedBytes,
Expand All @@ -199,7 +201,8 @@ bool MemoryPool::Stats::operator==(const MemoryPool::Stats& other) const {
other.numFrees,
other.numReserves,
other.numReleases,
other.numCollisions);
other.numCollisions,
other.numCapacityGrowths);
}

std::ostream& operator<<(std::ostream& os, const MemoryPool::Stats& stats) {
Expand Down Expand Up @@ -449,6 +452,11 @@ MemoryPoolImpl::~MemoryPoolImpl() {
"Bad memory usage track state: {}",
toString());

if (isRoot()) {
RECORD_HISTOGRAM_METRIC_VALUE(
kMetricMemoryPoolCapacityGrowCount, numCapacityGrowths_);
}

if (destructionCb_ != nullptr) {
destructionCb_(this);
}
Expand All @@ -470,6 +478,7 @@ MemoryPool::Stats MemoryPoolImpl::statsLocked() const {
stats.numReserves = numReserves_;
stats.numReleases = numReleases_;
stats.numCollisions = numCollisions_;
stats.numCapacityGrowths = numCapacityGrowths_;
return stats;
}

Expand Down Expand Up @@ -795,6 +804,7 @@ bool MemoryPoolImpl::incrementReservationThreadSafe(

VELOX_CHECK_NULL(parent_);

++numCapacityGrowths_;
if (growCapacityCb_(requestor, size)) {
TestValue::adjust(
"facebook::velox::memory::MemoryPoolImpl::incrementReservationThreadSafe::AfterGrowCallback",
Expand Down
21 changes: 16 additions & 5 deletions velox/common/memory/MemoryPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,11 @@ class MemoryPool : public std::enable_shared_from_this<MemoryPool> {
/// The number of internal memory reservation collisions caused by
/// concurrent memory requests.
uint64_t numCollisions{0};
/// The number of memory capacity growth attemps through the memory
/// arbitration.
///
/// NOTE: this only applies for the root memory pool.
uint64_t numCapacityGrowths{0};

bool operator==(const Stats& rhs) const;

Expand Down Expand Up @@ -1017,20 +1022,26 @@ class MemoryPoolImpl : public MemoryPool {

// Stats counters.
// The number of memory allocations.
std::atomic<uint64_t> numAllocs_{0};
std::atomic_uint64_t numAllocs_{0};

// The number of memory frees.
std::atomic<uint64_t> numFrees_{0};
std::atomic_uint64_t numFrees_{0};

// The number of external memory reservations made through maybeReserve().
std::atomic<uint64_t> numReserves_{0};
std::atomic_uint64_t numReserves_{0};

// The number of external memory releases made through release().
std::atomic<uint64_t> numReleases_{0};
std::atomic_uint64_t numReleases_{0};

// The number of internal memory reservation collisions caused by concurrent
// memory reservation requests.
std::atomic<uint64_t> numCollisions_{0};
std::atomic_uint64_t numCollisions_{0};

// The number of memory capacity growth attempts through the memory
// arbitration.
//
// NOTE: this only applies for root memory pool.
std::atomic_uint64_t numCapacityGrowths_{0};

// Mutex for 'debugAllocRecords_'.
std::mutex debugAllocMutex_;
Expand Down
10 changes: 10 additions & 0 deletions velox/docs/monitoring/metrics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ Memory Management
- Average
- The average of total free memory capacity which is managed by the
memory arbitrator.
* - memory_pool_initial_capacity_bytes
- Histogram
- The distribution of a root memory pool's initial capacity in range of [0 256MB]
with 32 buckets. It is configured to report the capacity at P50, P90, P99,
and P100 percentiles.
* - memory_pool_capacity_growth_count
- Histogram
- The distribution of a root memory pool cappacity growth attemps through
memory arbitration in range of [0, 256] with 32 buckets. It is configured
to report the count at P50, P90, P99, and P100 percentiles.
* - memory_pool_usage_leak_bytes
- Sum
- The leaf memory pool usage leak in bytes.
Expand Down

0 comments on commit 6760fb6

Please sign in to comment.