Skip to content

Commit

Permalink
add jemalloc compile flag & MemTracker is use only when jemalloc is a…
Browse files Browse the repository at this point in the history
…valable, depends on jemalloc to get accurate free size
  • Loading branch information
codesigner committed Dec 26, 2022
1 parent a15ddc8 commit 797fa05
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 17 deletions.
1 change: 1 addition & 0 deletions cmake/nebula/ThirdPartyConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ find_package(Glog REQUIRED)
find_package(Googletest REQUIRED)
if(ENABLE_JEMALLOC)
find_package(Jemalloc REQUIRED)
add_definitions(-DENABLE_JEMALLOC)
endif()
find_package(Libevent REQUIRED)
find_package(Proxygen REQUIRED)
Expand Down
11 changes: 6 additions & 5 deletions src/common/memory/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ inline ALWAYS_INLINE void* newImpl(std::size_t size, std::align_val_t align) {
throw std::bad_alloc{};
}

inline ALWAYS_INLINE void* newNoExept(std::size_t size) noexcept {
inline ALWAYS_INLINE void* newNoException(std::size_t size) noexcept {
return malloc(size);
}

inline ALWAYS_INLINE void* newNoExept(std::size_t size, std::align_val_t align) noexcept {
inline ALWAYS_INLINE void* newNoException(std::size_t size, std::align_val_t align) noexcept {
return aligned_alloc(static_cast<size_t>(align), size);
}

Expand Down Expand Up @@ -69,11 +69,12 @@ inline ALWAYS_INLINE size_t getActualAllocationSize(size_t size) {
}
return actual_size;
}

inline ALWAYS_INLINE size_t getActualAllocationSize(size_t size, std::align_val_t align) {
size_t actual_size = size;
/// The nallocx() function allocates no memory, but it performs the same size computation as the
/// mallocx() function
/// @note je_mallocx() != je_malloc(). It's expected they don't differ much in allocation logic.
// The nallocx() function allocates no memory, but it performs the same size computation as the
// mallocx() function
// @note je_mallocx() != je_malloc(). It's expected they don't differ much in allocation logic.
if (LIKELY(size != 0)) {
actual_size = nallocx(size, MALLOCX_ALIGN(alignToSizeT(align)));
}
Expand Down
2 changes: 1 addition & 1 deletion src/common/memory/MemoryTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class MemoryStats {
inline ALWAYS_INLINE void alloc(int64_t size) {
int64_t willBe = threadMemoryStats_.reserved - size;

if UNLIKELY (willBe < 0) {
if (UNLIKELY(willBe < 0)) {
// if local reserved is not enough, calculate how many bytes needed to get from global.
int64_t getFromGlobal = kLocalReservedLimit_;
while (willBe + getFromGlobal <= 0) {
Expand Down
20 changes: 16 additions & 4 deletions src/common/memory/MemoryUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
#include "common/memory/MemoryUtils.h"

#include <gflags/gflags.h>
#if ENABLE_JEMALLOC
#include <jemalloc/jemalloc.h>

#include "common/time/WallClock.h"
#endif
#include <algorithm>
#include <fstream>

#include "common/fs/FileUtils.h"
#include "common/memory/MemoryTracker.h"
#include "common/time/WallClock.h"

#define STRINGIFY_HELPER(x) #x
#define STRINGIFY(x) STRINGIFY_HELPER(x)
Expand Down Expand Up @@ -42,7 +44,12 @@ DEFINE_string(cgroup_v2_memory_current_path,

DEFINE_bool(memory_purge_enabled, true, "memory purge enabled, default true");
DEFINE_int32(memory_purge_interval_seconds, 10, "memory purge interval in seconds, default 10");
DEFINE_bool(memory_stats_detail_log, false, "print memory stats detail log");
DEFINE_bool(memory_tracker_detail_log, false, "print memory stats detail log");
DEFINE_double(memory_tracker_untracked_reserved_memory_mb,
50,
"memory tacker tracks memory of new/delete, this flag defined reserved untracked "
"memory (direct call malloc/free)");
DEFINE_double(memory_tracker_limit_ratio, 1, "memory tacker usable memory ratio to total limit");

using nebula::fs::FileUtils;

Expand Down Expand Up @@ -103,8 +110,12 @@ StatusOr<bool> MemoryUtils::hitsHighWatermark() {
}
}

// set limit
memory::MemoryStats::instance().setLimit(total * FLAGS_system_memory_high_watermark_ratio);
// MemoryStats depends on jemalloc
#if ENABLE_JEMALLOC
// set MemoryStats limit (MemoryTracker track-able memory)
memory::MemoryStats::instance().setLimit(
(total - FLAGS_memory_tracker_untracked_reserved_memory_mb) *
FLAGS_memory_tracker_limit_ratio);

// purge if enabled
if (FLAGS_memory_purge_enabled) {
Expand Down Expand Up @@ -138,6 +149,7 @@ StatusOr<bool> MemoryUtils::hitsHighWatermark() {
<< " usr_total:" << memory::MemoryStats::instance().getLimit()
<< " usr_ratio:" << memory::MemoryStats::instance().usedRatio();
}
#endif

auto hits = (1 - available / total) > FLAGS_system_memory_high_watermark_ratio;
LOG_IF_EVERY_N(WARNING, hits, 100)
Expand Down
20 changes: 13 additions & 7 deletions src/common/memory/NewDelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@

#include "common/memory/Memory.h"
/// Replace default new/delete with memory tracking versions.

/// address_sanitizer has already override the new/delete operator
/// override new/delete operator only when address_sanitizer is off
/// Two condition need check before MemoryTracker is on
/// 1. jemalloc is used
/// MemoryTracker need jemalloc API to get accurate size of alloc/free memory.
#if ENABLE_JEMALLOC
/// 2. address_sanitizer is off
/// sanitizer has already override the new/delete operator,
/// only override new/delete operator only when address_sanitizer is off
#if defined(__has_feature)
#if not __has_feature(address_sanitizer)

/// new
void *operator new(std::size_t size) {
nebula::memory::trackMemory(size);
Expand All @@ -35,22 +40,22 @@ void *operator new[](std::size_t size, std::align_val_t align) {

void *operator new(std::size_t size, const std::nothrow_t &) noexcept {
nebula::memory::trackMemory(size);
return nebula::memory::newNoExept(size);
return nebula::memory::newNoException(size);
}

void *operator new[](std::size_t size, const std::nothrow_t &) noexcept {
nebula::memory::trackMemory(size);
return nebula::memory::newNoExept(size);
return nebula::memory::newNoException(size);
}

void *operator new(std::size_t size, std::align_val_t align, const std::nothrow_t &) noexcept {
nebula::memory::trackMemory(size, align);
return nebula::memory::newNoExept(size, align);
return nebula::memory::newNoException(size, align);
}

void *operator new[](std::size_t size, std::align_val_t align, const std::nothrow_t &) noexcept {
nebula::memory::trackMemory(size, align);
return nebula::memory::newNoExept(size, align);
return nebula::memory::newNoException(size, align);
}

/// delete
Expand Down Expand Up @@ -96,3 +101,4 @@ void operator delete[](void *ptr, std::size_t size, std::align_val_t align) noex

#endif
#endif
#endif

0 comments on commit 797fa05

Please sign in to comment.