From 5005265135ccaefbe73cad620cb6a04bb53ac128 Mon Sep 17 00:00:00 2001 From: Yufccode Date: Mon, 6 May 2024 16:02:29 +0800 Subject: [PATCH 1/5] feat logs and test utils --- include/common.hpp | 15 ++++++---- include/log.hpp | 42 +++++++++++++++++++++++++++ tcmalloc.hpp => include/tcmalloc.hpp | 6 ++-- makefile | 2 +- src/central_cache.cc | 7 ++++- src/page_cache.cc | 3 ++ src/thread_cache.cc | 6 +++- test | Bin 39976 -> 49648 bytes unit_test.cc | 8 +++-- 9 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 include/log.hpp rename tcmalloc.hpp => include/tcmalloc.hpp (75%) diff --git a/include/common.hpp b/include/common.hpp index 9aec284..61e033b 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -7,6 +7,14 @@ #include #include +#if defined(_WIN32) || defined(_WIN64) +#include +#elif defined(__aarch64__) // ... +#include +#else +#include +#endif + static const size_t MAX_BYTES = 256 * 1024; // 256kb static const size_t BUCKETS_NUM = 208; // 一共208个桶 static const size_t PAGES_NUM = 129; // pageCahche设置128个桶 @@ -21,14 +29,11 @@ typedef size_t PAGE_ID; inline static void* system_alloc(size_t kpage) { void* ptr = nullptr; #if defined(_WIN32) || defined(_WIN64) -#include - *ptr = VirtualAlloc(0, kpage * (1 << 12), MEM_COMMIT | MEM_RESERVE, + ptr = VirtualAlloc(0, kpage << 13, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); #elif defined(__aarch64__) // ... -#include - void* ptr = mmap(NULL, kpage << 13, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ptr = mmap(NULL, kpage << 13, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); #else -#include std::cerr << "unknown system" << std::endl; throw std::bad_alloc(); #endif diff --git a/include/log.hpp b/include/log.hpp new file mode 100644 index 0000000..c919780 --- /dev/null +++ b/include/log.hpp @@ -0,0 +1,42 @@ + + +#ifndef __YUFC_LOG__ +#define __YUFC_LOG__ + +#include +#include + +enum STATUES // 日志等级 +{ + INFO, + DEBUG, + WARNING, + ERROR, + FATAL +}; +// LOG() << "message" +inline std::ostream& Log(const std::string& level, const std::string& file_name, int line) { +#ifdef PROJECT_DEBUG + // 添加日志等级 + std::string message = "["; + message += level; + message += "]"; + // 添加报错文件名称 + message += "["; + message += file_name; + message += "]"; + // 添加当前文件的行数 + message += "["; + message += std::to_string(line); + message += "]"; + // cout 本质内部是包含缓冲区的 + std::cout << message << " "; // 不要endl进行刷新 +#else +#endif + return std::cout; +} + +// 这种就是开放式的日志 +#define LOG(level) Log(#level, __FILE__, __LINE__) + +#endif \ No newline at end of file diff --git a/tcmalloc.hpp b/include/tcmalloc.hpp similarity index 75% rename from tcmalloc.hpp rename to include/tcmalloc.hpp index 38d3f6f..a5e5a40 100644 --- a/tcmalloc.hpp +++ b/include/tcmalloc.hpp @@ -2,13 +2,15 @@ #ifndef __YUFC_TCMALLOC_HPP__ #define __YUFC_TCMALLOC_HPP__ -#include "./include/common.hpp" -#include "./include/thread_cache.hpp" +#include "common.hpp" +#include "log.hpp" +#include "thread_cache.hpp" static void* tcmalloc(size_t size) { if (p_tls_thread_cache == nullptr) // 相当于单例 p_tls_thread_cache = new thread_cache; + LOG(DEBUG) << "tcmalloc find tc from mem" << std::endl; return p_tls_thread_cache->allocate(size); } diff --git a/makefile b/makefile index 27091e1..20d9127 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ test: *.cc ./src/*.cc - g++ -o $@ $^ -std=c++11 -lpthread + g++ -o $@ $^ -std=c++11 -lpthread #-DPROJECT_DEBUG .PHONY:clean clean: rm -f test \ No newline at end of file diff --git a/src/central_cache.cc b/src/central_cache.cc index be3ec20..83a1e39 100644 --- a/src/central_cache.cc +++ b/src/central_cache.cc @@ -1,12 +1,14 @@ #include "../include/central_cache.hpp" #include "../include/page_cache.hpp" +#include "../include/log.hpp" central_cache central_cache::__s_inst; size_t central_cache::fetch_range_obj(void*& start, void*& end, size_t batch_num, size_t size) { size_t index = size_class::bucket_index(size); // 算出在哪个桶找 __span_lists[index].__bucket_mtx.lock(); // 加锁(可以考虑RAII) + LOG(DEBUG) << "central_cache::fetch_range_obj() call central_cache::get_non_empty_span()" << std::endl; span* cur_span = get_non_empty_span(__span_lists[index], size); // 找一个非空的span(有可能找不到) assert(cur_span); assert(cur_span->__free_list); // 这个非空的span一定下面挂着内存了,所以断言一下 @@ -37,14 +39,16 @@ span* central_cache::get_non_empty_span(span_list& list, size_t size) { return it; it = it->__next; } + LOG(DEBUG) << "central_cache::get_non_empty_span() cannot find non-null span in cc, goto pc for mem" << std::endl; // 这里先解开桶锁 list.__bucket_mtx.unlock(); // 如果走到这里,说明没有空闲的span了,就要找pc了 + LOG(DEBUG) << "central_cache::get_non_empty_span() call page_cache::get_instance()->new_span()" << std::endl; page_cache::get_instance()->__page_mtx.lock(); span* cur_span = page_cache::get_instance()->new_span(size_class::num_move_page(size)); page_cache::get_instance()->__page_mtx.unlock(); - + LOG(DEBUG) << "central_cache::get_non_empty_span() get new span success" << std::endl; // 切分的逻辑 // 1. 计算span的大块内存的起始地址和大块内存的大小(字节数) char* addr_start = (char*)(cur_span->__page_id << PAGE_SHIFT); @@ -54,6 +58,7 @@ span* central_cache::get_non_empty_span(span_list& list, size_t size) { cur_span->__free_list = addr_start; // 先切一块下来做头 addr_start += size; void* tail = cur_span->__free_list; + LOG(DEBUG) << "central_cache::get_non_empty_span() cut span" << std::endl; while(addr_start < addr_end) { free_list::__next_obj(tail) = addr_start; tail = free_list::__next_obj(tail); diff --git a/src/page_cache.cc b/src/page_cache.cc index 926a7b0..345887e 100644 --- a/src/page_cache.cc +++ b/src/page_cache.cc @@ -1,5 +1,6 @@ #include "../include/page_cache.hpp" +#include "../include/log.hpp" page_cache page_cache::__s_inst; @@ -32,9 +33,11 @@ span* page_cache::new_span(size_t k) { */ // 剩下的挂到相应位置 __span_lists[n_span->__n].push_front(n_span); + LOG(DEBUG) << "page_cache::new_span() have span, return" << std::endl; return k_span; } } + LOG(DEBUG) << "page_cache::new_span() cannot find span, goto os for mem" << std::endl; // 走到这里,说明找不到span了:找os要 span* big_span = new span; void* ptr = system_alloc(PAGES_NUM - 1); diff --git a/src/thread_cache.cc b/src/thread_cache.cc index ef11659..4eeed60 100644 --- a/src/thread_cache.cc +++ b/src/thread_cache.cc @@ -2,6 +2,7 @@ #include "../include/thread_cache.hpp" #include "../include/central_cache.hpp" +#include "../include/log.hpp" void* thread_cache::allocate(size_t size) { assert(size <= MAX_BYTES); @@ -11,6 +12,7 @@ void* thread_cache::allocate(size_t size) { return __free_lists[bucket_index].pop(); } else { // 这个桶下面没有内存了!找centralCache找 + LOG(DEBUG) << "thread_cache::allocate call thread_cache::fetch_from_central_cache" << std::endl; return fetch_from_central_cache(bucket_index, align_size); } } @@ -35,8 +37,10 @@ void* thread_cache::fetch_from_central_cache(size_t index, size_t size) { // 开始获取内存了 void* start = nullptr; void* end = nullptr; + LOG(DEBUG) << "thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj()" << std::endl; size_t actual_n = central_cache::get_instance()->fetch_range_obj(start, end, batch_num, size); - assert(actual_n > 1); + LOG(DEBUG) << "actual_n" << ":" <= 1); if (actual_n == 1) { assert(start == end); return start; diff --git a/test b/test index 2d92d5f2e90d7f1304bfa11e0039d1d358912bbf..15d437fef79e91bf43bbba71cbc6de09c83d0e69 100755 GIT binary patch literal 49648 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 literal 39976 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 DYwE #include @@ -17,7 +17,11 @@ void tls_test() { t2.join(); } +void test_alloc() { + void* ptr = tcmalloc(6); +} + int main() { - tls_test(); + test_alloc(); return 0; } \ No newline at end of file From 57b6cfa09d403fdf8ba577cd4438f17532115412 Mon Sep 17 00:00:00 2001 From: Yufccode Date: Tue, 7 May 2024 10:41:32 +0800 Subject: [PATCH 2/5] update test 1 --- README.md | 80 ++++++++++++++++++++++++++++++++++++++++++- include/log.hpp | 3 -- include/tcmalloc.hpp | 2 ++ makefile | 2 +- src/central_cache.cc | 16 +++++++-- src/page_cache.cc | 4 +++ src/thread_cache.cc | 11 ++++-- test | Bin 49648 -> 50552 bytes unit_test.cc | 17 +++++++-- 9 files changed, 123 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a618566..3c06394 100644 --- a/README.md +++ b/README.md @@ -894,4 +894,82 @@ span* central_cache::get_non_empty_span(span_list& list, size_t size) { } ``` -## 内存申请流程联调 \ No newline at end of file +## 内存申请流程联调 + +先给每一步打上日志,看看调用的流程。 + +然后多次调用tcmalloc,看看日志。 + +unit_test.cc +```cpp +void test_alloc() { + std::cout << "call tcmalloc(1)" << std::endl; + void* ptr = tcmalloc(8 * 1024); + std::cout << "call tcmalloc(2)" << std::endl; + ptr = tcmalloc(10); + std::cout << "call tcmalloc(3)" << std::endl; + ptr = tcmalloc(2); + std::cout << "call tcmalloc(4)" << std::endl; + ptr = tcmalloc(1); + std::cout << "call tcmalloc(5)" << std::endl; + ptr = tcmalloc(1); + std::cout << "call tcmalloc(6)" << std::endl; + ptr = tcmalloc(5); + std::cout << "call tcmalloc(7)" << std::endl; + ptr = tcmalloc(1); +} +``` + +输出日志: +```bash +call tcmalloc(1) +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/central_cache.cc][45] central_cache::get_non_empty_span() cannot find non-null span in cc, goto pc for mem +[DEBUG][src/central_cache.cc][52] central_cache::get_non_empty_span() call page_cache::get_instance()->new_span() +[DEBUG][src/page_cache.cc][43] page_cache::new_span() cannot find span, goto os for mem +[DEBUG][src/page_cache.cc][37] page_cache::new_span() have span, return +[DEBUG][src/central_cache.cc][58] central_cache::get_non_empty_span() get new span success +[DEBUG][src/central_cache.cc][70] central_cache::get_non_empty_span() cut span +[DEBUG][src/thread_cache.cc][47] actual_n:1 +call tcmalloc(2) +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/central_cache.cc][45] central_cache::get_non_empty_span() cannot find non-null span in cc, goto pc for mem +[DEBUG][src/central_cache.cc][52] central_cache::get_non_empty_span() call page_cache::get_instance()->new_span() +[DEBUG][src/page_cache.cc][37] page_cache::new_span() have span, return +[DEBUG][src/central_cache.cc][58] central_cache::get_non_empty_span() get new span success +[DEBUG][src/central_cache.cc][70] central_cache::get_non_empty_span() cut span +[DEBUG][src/thread_cache.cc][47] actual_n:1 +call tcmalloc(3) +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/central_cache.cc][45] central_cache::get_non_empty_span() cannot find non-null span in cc, goto pc for mem +[DEBUG][src/central_cache.cc][52] central_cache::get_non_empty_span() call page_cache::get_instance()->new_span() +[DEBUG][src/page_cache.cc][37] page_cache::new_span() have span, return +[DEBUG][src/central_cache.cc][58] central_cache::get_non_empty_span() get new span success +[DEBUG][src/central_cache.cc][70] central_cache::get_non_empty_span() cut span +[DEBUG][src/thread_cache.cc][47] actual_n:1 +call tcmalloc(4) +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:2 +call tcmalloc(5) +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +call tcmalloc(6) +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:3 +call tcmalloc(7) +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +``` diff --git a/include/log.hpp b/include/log.hpp index c919780..39cf46b 100644 --- a/include/log.hpp +++ b/include/log.hpp @@ -16,7 +16,6 @@ enum STATUES // 日志等级 }; // LOG() << "message" inline std::ostream& Log(const std::string& level, const std::string& file_name, int line) { -#ifdef PROJECT_DEBUG // 添加日志等级 std::string message = "["; message += level; @@ -31,8 +30,6 @@ inline std::ostream& Log(const std::string& level, const std::string& file_name, message += "]"; // cout 本质内部是包含缓冲区的 std::cout << message << " "; // 不要endl进行刷新 -#else -#endif return std::cout; } diff --git a/include/tcmalloc.hpp b/include/tcmalloc.hpp index a5e5a40..d2da5b6 100644 --- a/include/tcmalloc.hpp +++ b/include/tcmalloc.hpp @@ -10,7 +10,9 @@ static void* tcmalloc(size_t size) { if (p_tls_thread_cache == nullptr) // 相当于单例 p_tls_thread_cache = new thread_cache; +#ifdef PROJECT_DEBUG LOG(DEBUG) << "tcmalloc find tc from mem" << std::endl; +#endif return p_tls_thread_cache->allocate(size); } diff --git a/makefile b/makefile index 20d9127..98302dd 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ test: *.cc ./src/*.cc - g++ -o $@ $^ -std=c++11 -lpthread #-DPROJECT_DEBUG + g++ -o $@ $^ -std=c++11 -lpthread -DPROJECT_DEBUG .PHONY:clean clean: rm -f test \ No newline at end of file diff --git a/src/central_cache.cc b/src/central_cache.cc index 83a1e39..b5becd8 100644 --- a/src/central_cache.cc +++ b/src/central_cache.cc @@ -1,14 +1,16 @@ #include "../include/central_cache.hpp" -#include "../include/page_cache.hpp" #include "../include/log.hpp" +#include "../include/page_cache.hpp" central_cache central_cache::__s_inst; size_t central_cache::fetch_range_obj(void*& start, void*& end, size_t batch_num, size_t size) { size_t index = size_class::bucket_index(size); // 算出在哪个桶找 __span_lists[index].__bucket_mtx.lock(); // 加锁(可以考虑RAII) +#ifdef PROJECT_DEBUG LOG(DEBUG) << "central_cache::fetch_range_obj() call central_cache::get_non_empty_span()" << std::endl; +#endif span* cur_span = get_non_empty_span(__span_lists[index], size); // 找一个非空的span(有可能找不到) assert(cur_span); assert(cur_span->__free_list); // 这个非空的span一定下面挂着内存了,所以断言一下 @@ -39,16 +41,22 @@ span* central_cache::get_non_empty_span(span_list& list, size_t size) { return it; it = it->__next; } +#ifdef PROJECT_DEBUG LOG(DEBUG) << "central_cache::get_non_empty_span() cannot find non-null span in cc, goto pc for mem" << std::endl; +#endif // 这里先解开桶锁 list.__bucket_mtx.unlock(); - // 如果走到这里,说明没有空闲的span了,就要找pc了 +// 如果走到这里,说明没有空闲的span了,就要找pc了 +#ifdef PROJECT_DEBUG LOG(DEBUG) << "central_cache::get_non_empty_span() call page_cache::get_instance()->new_span()" << std::endl; +#endif page_cache::get_instance()->__page_mtx.lock(); span* cur_span = page_cache::get_instance()->new_span(size_class::num_move_page(size)); page_cache::get_instance()->__page_mtx.unlock(); +#ifdef PROJECT_DEBUG LOG(DEBUG) << "central_cache::get_non_empty_span() get new span success" << std::endl; +#endif // 切分的逻辑 // 1. 计算span的大块内存的起始地址和大块内存的大小(字节数) char* addr_start = (char*)(cur_span->__page_id << PAGE_SHIFT); @@ -58,8 +66,10 @@ span* central_cache::get_non_empty_span(span_list& list, size_t size) { cur_span->__free_list = addr_start; // 先切一块下来做头 addr_start += size; void* tail = cur_span->__free_list; +#ifdef PROJECT_DEBUG LOG(DEBUG) << "central_cache::get_non_empty_span() cut span" << std::endl; - while(addr_start < addr_end) { +#endif + while (addr_start < addr_end) { free_list::__next_obj(tail) = addr_start; tail = free_list::__next_obj(tail); addr_start += size; diff --git a/src/page_cache.cc b/src/page_cache.cc index 345887e..d549d67 100644 --- a/src/page_cache.cc +++ b/src/page_cache.cc @@ -33,11 +33,15 @@ span* page_cache::new_span(size_t k) { */ // 剩下的挂到相应位置 __span_lists[n_span->__n].push_front(n_span); +#ifdef PROJECT_DEBUG LOG(DEBUG) << "page_cache::new_span() have span, return" << std::endl; +#endif return k_span; } } +#ifdef PROJECT_DEBUG LOG(DEBUG) << "page_cache::new_span() cannot find span, goto os for mem" << std::endl; +#endif // 走到这里,说明找不到span了:找os要 span* big_span = new span; void* ptr = system_alloc(PAGES_NUM - 1); diff --git a/src/thread_cache.cc b/src/thread_cache.cc index 4eeed60..2a603e1 100644 --- a/src/thread_cache.cc +++ b/src/thread_cache.cc @@ -12,7 +12,9 @@ void* thread_cache::allocate(size_t size) { return __free_lists[bucket_index].pop(); } else { // 这个桶下面没有内存了!找centralCache找 +#ifdef PROJECT_DEBUG LOG(DEBUG) << "thread_cache::allocate call thread_cache::fetch_from_central_cache" << std::endl; +#endif return fetch_from_central_cache(bucket_index, align_size); } } @@ -37,9 +39,14 @@ void* thread_cache::fetch_from_central_cache(size_t index, size_t size) { // 开始获取内存了 void* start = nullptr; void* end = nullptr; - LOG(DEBUG) << "thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj()" << std::endl; +#ifdef PROJECT_DEBUG + LOG(DEBUG) << "thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj()" << std::endl; +#endif size_t actual_n = central_cache::get_instance()->fetch_range_obj(start, end, batch_num, size); - LOG(DEBUG) << "actual_n" << ":" <= 1); if (actual_n == 1) { assert(start == end); diff --git a/test b/test index 15d437fef79e91bf43bbba71cbc6de09c83d0e69..efbbe253af22eda9c034d3dc2edd28b053e2e09d 100755 GIT binary patch literal 50552 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 literal 49648 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 diff --git a/unit_test.cc b/unit_test.cc index a6b4f26..04ce9e3 100644 --- a/unit_test.cc +++ b/unit_test.cc @@ -1,8 +1,8 @@ #include "./include/tcmalloc.hpp" -#include #include +#include void alloc1() { for (size_t i = 0; i < 5; i++) { @@ -18,7 +18,20 @@ void tls_test() { } void test_alloc() { - void* ptr = tcmalloc(6); + std::cout << "call tcmalloc(1)" << std::endl; + void* ptr = tcmalloc(8 * 1024); + std::cout << "call tcmalloc(2)" << std::endl; + ptr = tcmalloc(10); + std::cout << "call tcmalloc(3)" << std::endl; + ptr = tcmalloc(2); + std::cout << "call tcmalloc(4)" << std::endl; + ptr = tcmalloc(1); + std::cout << "call tcmalloc(5)" << std::endl; + ptr = tcmalloc(1); + std::cout << "call tcmalloc(6)" << std::endl; + ptr = tcmalloc(5); + std::cout << "call tcmalloc(7)" << std::endl; + ptr = tcmalloc(1); } int main() { From e4466d21243eace17bb9999701a3b5949f5b1752 Mon Sep 17 00:00:00 2001 From: Yufccode Date: Tue, 7 May 2024 12:26:57 +0800 Subject: [PATCH 3/5] central_cache free mem done --- README.md | 138 +++++ include/central_cache.hpp | 7 + include/common.hpp | 18 +- include/page_cache.hpp | 5 +- include/thread_cache.hpp | 3 + makefile | 4 +- src/central_cache.cc | 38 +- src/page_cache.cc | 18 + src/thread_cache.cc | 28 +- test | Bin 50552 -> 0 bytes test/test1.log | 1223 +++++++++++++++++++++++++++++++++++++ unit_test.cc | 11 +- 12 files changed, 1477 insertions(+), 16 deletions(-) delete mode 100755 test create mode 100644 test/test1.log diff --git a/README.md b/README.md index 3c06394..673ed55 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ - [获取span详解](#获取span详解) - [关于 new\_span 如何加锁的文字(重要/容易出bug)](#关于-new_span-如何加锁的文字重要容易出bug) - [内存申请流程联调](#内存申请流程联调) + - [thread\_cache内存释放](#thread_cache内存释放) + - [central\_cache内存释放](#central_cache内存释放) *** @@ -973,3 +975,139 @@ call tcmalloc(6) call tcmalloc(7) [DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem ``` + + +同样,再测一次。 + +```cpp +void test_alloc2() { + for (size_t i = 0; i < 1024; ++i) { + void* p1 = tcmalloc(6); + } + void* p2 = tcmalloc(6); // 这一次一定会找新的span +} +``` + +如果申请1024次6字节(对齐后为8字节),第1025次申请,一定会向系统申请新的span了,之前都不需要的!所以预期输出只有两个`goto os for mem`。 + +输出日志放在了 `./test/test1.log` 。 + + +## thread_cache内存释放 + +当链表长度大于一次批量申请的内存的时候,就开始还一段list给cc + +thread_cache.cc +```cpp +void thread_cache::deallocate(void* ptr, size_t size) { + assert(ptr); + assert(size <= MAX_BYTES); + size_t index = size_class::bucket_index(size); + __free_lists[index].push(ptr); + // 当链表长度大于一次批量申请的内存的时候,就开始还一段list给cc + if (__free_lists[index].size() >= __free_lists[index].max_size()) { + list_too_long(__free_lists[index], size); + } +} +``` + +thread_cache.cc +```cpp +void thread_cache::list_too_long(free_list& list, size_t size) { + void* start = nullptr; + void* end = nullptr; + list.pop(start, end, list.max_size()); + central_cache::get_instance()->release_list_to_spans(start, size); +} +``` + +tcmalloc的规则更复杂,可能还会控制内存大小,超过...就会释放等。 + + +## central_cache内存释放 + +```cpp +void central_cache::release_list_to_spans(void* start, size_t size) { + size_t index = size_class::bucket_index(size); // 先算一下在哪一个桶里面 + __span_lists[index].__bucket_mtx.lock(); + // 这里要注意,一个桶挂了多个span,这些内存块挂到哪一个span是不确定的 + + __span_lists[index].__bucket_mtx.unlock(); +} +``` + +**这里的问题是:如何确定每一块内存块应该到哪一个span里面去。** + + +现在要判断,这些内存块,是来自哪个span的,然后span是从page切出来的,page是有地址的,span也是有地址的。 + +所以最好在page里面的时候,先让pageid和span的地址映射起来先。 + +在pc.hpp里面增加。 +```cpp +std::unordered_map __id_span_map; +``` + +**然后在new_span里面,把新的span分给cc的时候,记录一下映射。** + +然后pc里面提供一个方法,获取对象到span映射。 + +page_cache.cc +```cpp +span* page_cache::map_obj_to_span(void* obj) { + // 先把页号算出来 + PAGE_ID id = (PAGE_ID)obj >> PAGE_SHIFT; // 这个理论推导可以自行推导一下 + auto ret = __id_span_map.find(id); + if (ret != __id_span_map.end()) + return ret->second; + LOG(FATAL); + assert(false); + return nullptr; +} +``` + +此时就可以通过一个对象,获取到对应是哪一个span了。 + +此时就可以继续写`release_list_to_spans`了。 + +```cpp +void central_cache::release_list_to_spans(void* start, size_t size) { + size_t index = size_class::bucket_index(size); // 先算一下在哪一个桶里面 + __span_lists[index].__bucket_mtx.lock(); + // 这里要注意,一个桶挂了多个span,这些内存块挂到哪一个span是不确定的 + while (start) { + // 遍历这个链表 + void* next = free_list::__next_obj(start); // 先记录一下下一个,避免等下找不到了 + span* cur_span = page_cache::get_instance()->map_obj_to_span(start); + free_list::__next_obj(start) = cur_span->__free_list; + cur_span->__free_list = start; + // 处理usecount + cur_span->__use_count--; + if (cur_span->__use_count == 0) { + // 说明这个span切分出去的所有小块都回来了 + // 归还给pagecache + // 1. 把这一页从cc的这个桶的spanlist中拿掉 + __span_lists[index].erase(cur_span); // 从桶里面拿走 + // 2. 此时不用管这个span的freelist了,因为这些内存本来就是span初始地址后面的,然后顺序也是乱的,直接置空即可 + // (这里还不太理解) + cur_span->__free_list = nullptr; + cur_span->__next = cur_span->__prev = nullptr; + // 页号,页数是不能动的! + // 3. 解开桶锁 + __span_lists[index].__bucket_mtx.unlock(); + // 4. 还给pc + page_cache::get_instance()->__page_mtx.lock(); + page_cache::get_instance()->release_span_to_page(cur_span); + page_cache::get_instance()->__page_mtx.unlock(); + // 5. 恢复桶锁 + __span_lists[index].__bucket_mtx.lock(); + } + start = next; + } + __span_lists[index].__bucket_mtx.unlock(); +} +``` + +细节在注释里面写的很清楚了。 + +要注意,调用pc的接口的时候,就记得把桶锁解掉。 \ No newline at end of file diff --git a/include/central_cache.hpp b/include/central_cache.hpp index 9e191c5..4765b37 100644 --- a/include/central_cache.hpp +++ b/include/central_cache.hpp @@ -13,8 +13,15 @@ class central_cache { central_cache(const central_cache&) = delete; // 不允许拷贝 public: static central_cache* get_instance() { return &__s_inst; } + // 将中心缓存获取一定数量的对象给threadCache size_t fetch_range_obj(void*& start, void*& end, size_t batch_num, size_t size); + // 获取一个非空的span span* get_non_empty_span(span_list& list, size_t size); + +public: + // 将一定数量的对象释放到span中 + void release_list_to_spans(void* start, size_t byte_size); + public: }; diff --git a/include/common.hpp b/include/common.hpp index 61e033b..d9b9dd6 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #if defined(_WIN32) || defined(_WIN64) #include @@ -47,25 +48,40 @@ class free_list { private: void* __free_list_ptr = nullptr; size_t __max_size = 1; + size_t __size = 0; public: void push(void* obj) { assert(obj); __next_obj(obj) = __free_list_ptr; __free_list_ptr = obj; + ++__size; } - void push(void* start, void* end) { + void push(void* start, void* end, size_t n) { __next_obj(end) = __free_list_ptr; __free_list_ptr = start; + __size += n; } void* pop() { assert(__free_list_ptr); void* obj = __free_list_ptr; __free_list_ptr = __next_obj(obj); + --__size; return obj; } + void pop(void*& start, void*& end, size_t n) { + // 这里是输出参数了 + assert(n >= __size); + start = __free_list_ptr; + for (size_t i = 0; i < n - 1; i++) + end = free_list::__next_obj(end); + __free_list_ptr = free_list::__next_obj(end); + free_list::__next_obj(end) = nullptr; + __size -= n; + } bool empty() { return __free_list_ptr == nullptr; } size_t& max_size() { return __max_size; } + size_t size() { return __size; } public: static void*& __next_obj(void* obj) { diff --git a/include/page_cache.hpp b/include/page_cache.hpp index bce6496..c4aa545 100644 --- a/include/page_cache.hpp +++ b/include/page_cache.hpp @@ -11,13 +11,16 @@ class page_cache { static page_cache __s_inst; page_cache() = default; page_cache(const page_cache&) = delete; + std::unordered_map __id_span_map; public: std::mutex __page_mtx; public: static page_cache* get_instance() { return &__s_inst; } - + span* map_obj_to_span(void* obj); + // 释放空闲的span回到pc,并合并相邻的span + void release_span_to_page(span* s); public: // 获取一个K页的span span* new_span(size_t k); diff --git a/include/thread_cache.hpp b/include/thread_cache.hpp index 649af41..9bb6f5a 100644 --- a/include/thread_cache.hpp +++ b/include/thread_cache.hpp @@ -14,7 +14,10 @@ class thread_cache { void deallocate(void* ptr, size_t size); public: + // 向centralCache获取内存 void* fetch_from_central_cache(size_t index, size_t size); + // 释放对象,链表过长的时候,回收内存到centralCache + void list_too_long(free_list& list, size_t size); }; static __thread thread_cache* p_tls_thread_cache = nullptr; diff --git a/makefile b/makefile index 98302dd..bdce528 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ -test: *.cc ./src/*.cc +test.out: *.cc ./src/*.cc g++ -o $@ $^ -std=c++11 -lpthread -DPROJECT_DEBUG .PHONY:clean clean: - rm -f test \ No newline at end of file + rm -f test.out \ No newline at end of file diff --git a/src/central_cache.cc b/src/central_cache.cc index b5becd8..d696421 100644 --- a/src/central_cache.cc +++ b/src/central_cache.cc @@ -28,7 +28,7 @@ size_t central_cache::fetch_range_obj(void*& start, void*& end, size_t batch_num } cur_span->__free_list = free_list::__next_obj(end); free_list::__next_obj(end) = nullptr; - + cur_span->__use_count += actual_n; // 拿走了几个,use_count记得加上去 __span_lists[index].__bucket_mtx.unlock(); // 解锁 return actual_n; } @@ -78,4 +78,40 @@ span* central_cache::get_non_empty_span(span_list& list, size_t size) { list.__bucket_mtx.lock(); list.push_front(cur_span); return cur_span; +} + +void central_cache::release_list_to_spans(void* start, size_t size) { + size_t index = size_class::bucket_index(size); // 先算一下在哪一个桶里面 + __span_lists[index].__bucket_mtx.lock(); + // 这里要注意,一个桶挂了多个span,这些内存块挂到哪一个span是不确定的 + while (start) { + // 遍历这个链表 + void* next = free_list::__next_obj(start); // 先记录一下下一个,避免等下找不到了 + span* cur_span = page_cache::get_instance()->map_obj_to_span(start); + free_list::__next_obj(start) = cur_span->__free_list; + cur_span->__free_list = start; + // 处理usecount + cur_span->__use_count--; + if (cur_span->__use_count == 0) { + // 说明这个span切分出去的所有小块都回来了 + // 归还给pagecache + // 1. 把这一页从cc的这个桶的spanlist中拿掉 + __span_lists[index].erase(cur_span); // 从桶里面拿走 + // 2. 此时不用管这个span的freelist了,因为这些内存本来就是span初始地址后面的,然后顺序也是乱的,直接置空即可 + // (这里还不太理解) + cur_span->__free_list = nullptr; + cur_span->__next = cur_span->__prev = nullptr; + // 页号,页数是不能动的! + // 3. 解开桶锁 + __span_lists[index].__bucket_mtx.unlock(); + // 4. 还给pc + page_cache::get_instance()->__page_mtx.lock(); + page_cache::get_instance()->release_span_to_page(cur_span); + page_cache::get_instance()->__page_mtx.unlock(); + // 5. 恢复桶锁 + __span_lists[index].__bucket_mtx.lock(); + } + start = next; + } + __span_lists[index].__bucket_mtx.unlock(); } \ No newline at end of file diff --git a/src/page_cache.cc b/src/page_cache.cc index d549d67..289cbe4 100644 --- a/src/page_cache.cc +++ b/src/page_cache.cc @@ -33,6 +33,10 @@ span* page_cache::new_span(size_t k) { */ // 剩下的挂到相应位置 __span_lists[n_span->__n].push_front(n_span); + // 这里记录映射(简历id和span的映射,方便cc回收小块内存时,查找对应的span) + for (PAGE_ID j = 0; j < k_span->__n; j++) { + __id_span_map[k_span->__page_id + j] = k_span; + } #ifdef PROJECT_DEBUG LOG(DEBUG) << "page_cache::new_span() have span, return" << std::endl; #endif @@ -50,4 +54,18 @@ span* page_cache::new_span(size_t k) { // 挂到上面去 __span_lists[PAGES_NUM - 1].push_front(big_span); return new_span(k); +} + +span* page_cache::map_obj_to_span(void* obj) { + // 先把页号算出来 + PAGE_ID id = (PAGE_ID)obj >> PAGE_SHIFT; // 这个理论推导可以自行推导一下 + auto ret = __id_span_map.find(id); + if (ret != __id_span_map.end()) + return ret->second; + LOG(FATAL); + assert(false); + return nullptr; +} + +void page_cache::release_span_to_page(span* s) { } \ No newline at end of file diff --git a/src/thread_cache.cc b/src/thread_cache.cc index 2a603e1..b046f5b 100644 --- a/src/thread_cache.cc +++ b/src/thread_cache.cc @@ -19,14 +19,6 @@ void* thread_cache::allocate(size_t size) { } } -void thread_cache::deallocate(void* ptr, size_t size) { - assert(ptr); - assert(size <= MAX_BYTES); - size_t index = size_class::bucket_index(size); - __free_lists[index].push(ptr); - // ... 如果太长了,还给centralCache -} - void* thread_cache::fetch_from_central_cache(size_t index, size_t size) { // 慢开始反馈调节算法 size_t batch_num = std::min(__free_lists[index].max_size(), size_class::num_move_size(size)); @@ -52,9 +44,27 @@ void* thread_cache::fetch_from_central_cache(size_t index, size_t size) { assert(start == end); return start; } else { - __free_lists[index].push(free_list::__next_obj(start), end); + __free_lists[index].push(free_list::__next_obj(start), end, actual_n - 1); return start; } return nullptr; +} + +void thread_cache::deallocate(void* ptr, size_t size) { + assert(ptr); + assert(size <= MAX_BYTES); + size_t index = size_class::bucket_index(size); + __free_lists[index].push(ptr); + // 当链表长度大于一次批量申请的内存的时候,就开始还一段list给cc + if (__free_lists[index].size() >= __free_lists[index].max_size()) { + list_too_long(__free_lists[index], size); + } +} + +void thread_cache::list_too_long(free_list& list, size_t size) { + void* start = nullptr; + void* end = nullptr; + list.pop(start, end, list.max_size()); + central_cache::get_instance()->release_list_to_spans(start, size); } \ No newline at end of file diff --git a/test b/test deleted file mode 100755 index efbbe253af22eda9c034d3dc2edd28b053e2e09d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50552 zcmeHwe|(hHmG_;=06|fLprX<;AZpYQX7W3Tb@(wrBx0IGMQi(HG8xE7l8MO#v9fJc zwxuoGGL^P&D{i#5i>&RkEp1^}+eqoVw9+=BwRD%d6QEt*mfeL)`;sj-@Auq$&&++E zJP(5XeBRId$37qN%>CYb&pr3tbI(2ZJ~KBTjn*&q`+NmLKLz4D!iUfOS1KT)@!c=! z40hZR*CX+$UU7%Qi#t?3ra>(~Q|=$Jqko%qzLPFd z>;zLPOV0%Sqt9M)QW<)R6cOBB!>`h9RBz}mmEoi>=n-bh?Y$rMsDJ1CaJ!AVJuf+z z>js$e_|5A`w$AHlo7<7>>RUfI7VC+(S5=hurb@%A-_sxniMnj%U1HC-uXuCPBUin@ z^M;qLH~#L)3TxZ8Yltn$K>Vl-Jyf3bMi1fqPXZV4zXEZw5SNdwP#~^?p>hvY{tPra zWo%LLQ53t(1>XnE4SxY0a>J*=$ldUpfV;K(2JFnO{3kr*`A?7XuY1VzJrDdI^vg}2 zZ74t6MGt?3-rVGTz(by9kMiI2D1XF5&PzS?u+?K6yFAA0rylK&^T4n37{{-8^y`-% z_`M$ddp!De+CvXZJ;rMz%Dau@QV%|r9_2p?Io#m(`n&^`tFJSar>JSZ#@( z#F}JpI?>a7$KsAuSE4!A+L2Is?m720-`$k1O{|Y6y3@&2m#_e=Y)V(9+j|nRwkoSB z9ZM&ofb(Fu(z-)8t4c+i(&12FSMtHWgw>tysax4(aYf`*v?W%@`a04Ot|O67)HQ{z zXtZJJx^=`AZ9~}3WEWalr&_7DtoZu%;c&RDHP)Mqqotl?*P6OGScT*5u^ubk6HBIh z>*CR-82%Scu8(#~P94C!3N<35T=7eRVItO9*K9S1tY}lU)wlwE^JulH!fL9tnn`3S z9ksY5995#GI(l`}6^X944!72$-VIk_%t)&qEqiulaX8wrBHp;7sr+3s=&mOQs_~j+ zs@H;E5*2k_$+WF!4NDuFQcac~``Xr6n-%NmNX1nlj8V+O@TVREBbZD$B!?~5np_ty z!{^?l74L}k_FCzOyAxKjYjsKuH|5D{R`0{G(@rbV)065+f=OFPgSG&>@hvGMb<6f- z`>+(tuvcr%`t??KqNg|273)Z*AGX$oNFo^FIgPmDfmE_fk0T8#wE8aX4>db;!y#u= zPE`=3DGjq6Yn5(x5pRY$R$6Lox*j5u$Tng z+3Hxb156Mq()=d}*BMK~IVmdulVn=NT2npg9G~7q$7*s{lf@?FA@&}qlfb2 zM*bHvpT~A#oOm>s?-%##{1D3TlKB(GW{s)x0i*mlu|Ve$|Ja!?V1+9bU(nctGCe_j zRi|J3`?dHqUVKZZ(>Hz=Tb=?jsM9^Nyk8tZnjYTI6=1!lXUlX&2lalB@dNKs_oFfrb3c42HV5sH{m>KC@(_;DDEDmA{C$vz z_pFrpq=8?QD=ox;fnRFi+YNlOf$ubMGydFd;8z&s2Ms)E;6nyJ%fJsA__YR}HE@dU z_&ILi^B4p@Y2Y+p_&Hu-4e5%2J z(7@?TfuH>bZf^C53|t?5$ts5oTu*6VWZ*Lme7b?pHt?W@~xexp%-xq-9G zqwEF)zu73i%E0Fuc#DCT8hE>boAa*Qz{5uQnZbgez5U4do`1VQWOfL#_3cMq-ac4h zy}?CJB5x8~T*YNWq`^kYW) z+eklar2i4=y(-Oi#gy#mJ)-~Md-3mA1!Bi=L1g5}wIcIt*y8}~PV8ScQh>Yw{(WwA z^a}^@PvWPSjYJS`9UC3JlI)f35qU#mKxCc)odtTE5WgK1q8aI(vraA>iJ{KP0^be+ zJEnTh^0S0^W%k*RzP51Eqo0~}cHt8*qx`d|yXefakycsPpQ}r4zWvB|<=lDeVlnbf zwAu1(q&DIcmEgNmyuNItA9Z9Kfyl^Rko^$;1x0^j%d?{Pt&1ZgZ$GkE&Nr6-F#7ZM zBj3sK%w8!*B(HtTMtmYNGQ3QH_8*K4-SRWMiO7hE$bgQ(=bc*U6U}1a(SvKy##_*3 zwqWXxlRmN4EQ>W_Bzsh3K8rF$k6!D`96?zD7wr?JnQTG9j&!YZbUwd$gm|Lf6`Hq9gU4l*hCC5aQ(o%Z z@RgB~DHn;Y!CXw)1O8uuvX~;U*;y_k9N+O zINF;d<(RtTcF3tUI9r`N}^D>Y5`x~V$p(moE ze_rON;One+1YMuW|25`!VCOOt=YV-ScECno!a{o?kBkxz5lC2PqP z@&QA7r#QQ8q!xK@?GA$vWNXCQ@P&Na|D^1>$@lzQ1%*4Z^TZy>hwb_XW!Kqxkv(F= z%%<$9sLhT>YB9eb?8o{+c(y>SARCmQ7mGa$;rFtOBYVb?EiOZ!P(HgXvL`6S#it9z zP2|sNNI#%B=il+{xc$464^Tep@!YLI`UrRqgU@x~OZ{UxkKACNBLmPA z_8@AGpp8?+6LaE9@Id>rofjoGZO3K6p3(VlH7$Jp?MHr~=Zdk`U~XevMvgdjqt_f- z6QsPLwsm7*u3R^MDf#;{KP3uZJB&H~IzAu4XF+pukjnXYeAC2aUH^`+bDe7pEXGFOr?#1pMe@R1Rs#IpoVK zIWxd0e=72+d=lwl=vUTpS%ZRDgC_HM6!*!7589&|E7`NN3Ae2y}?`3s+y#oC2)jICmZxQymV1a0~tKk?+4hSxIkU92;? zhF~2dAD?|(Wd2q9L$pV06V`LA;gY8iqLFw*o}0MtQN#hZH6LxBI7>SA-SqY&YTe>K zQa^^#k1YBDUHvwD<=--)k9ve zaPW&HH?@UBttlk;o3JDFN7>Nh${vR&h&`AudtfVj(DwTw@1C28PXT26@|MPyTX*yX zHw=79oNakcY#7({*d)Y78~oP1-oUn;KGdKGl-2UIA&GPdc@!%&gcj>c~jn*ct zN3wmi4gMLowgveL$U|jkwYSvJydjxzjxo?H}XhkZqIAo<2CLYDf_e?_v-eDN0j)Zon~N1{|GsZHIID+jS2e$#$=mAh;^~A z(qm@xlRRd$-($VN21ia}T&S)Ou{ot-2gr|%Ohw#6dO1pCNInHJ)j&2HC%Gn|%=aK4 z;Wv`}a!<%(p!SyJKgm95JmDusmTLX5uVG*2EJret9`oh$F}?IJXnP^)3F|)QyY#=X zt5Xrg6(l?5Ng0tx`jmSy-3O9^>Y%*Tk3Igjw=>3e^d90Zv_ZOg3UX!?%k5%!lf-jRMnt*IpMfo2P6zv(M!*PqItq#h8~3 zkZuZGczBhEohToIdeVo0e&@fP^Vlvw&2wt!7bxdtCjxedqx5sy(z)`77h|nO8}M6O zu`k~`#lh=*^gwkGqvZ7I^rhr;Xe_i3xQW~F@`)r5&a-m-&M8A&)JnU?eEb9SMZQd& zV-B9rxCIf{sdfCDxw8_)awEf73y;9Z9feOjhP9K%GWg0xLqcr4c0zFqB zj-an{Owp$vj2GhS5$v0#Uz~-tMj(zV7`!!e1TxWQALJz}vhT|XY6E4(w6W#=>Z~na zK6qQ^^oT0&LwUr=Y7R+?v|K~P$Y`~I|HT;GB1SO3rx8x}Kxd`oqq$tR8aSPop?vlh z{TX!-?-Bm$F!FChEIpgnOU>ioz=L>^&u@XxCmW&to&W{*;4^0tbLz6Mb9?BYZyNY& z{3o>U#~L+!8)P|$UA%~LBp2y+K-<{SHIBWB?OfEK*$w^V_MfnqW27&PLzV?$1&l4kbriZ!J$khPN1kSh+_sdX(r z{`kQl_F7j$=5}BlqrQT)_RBl|n#L0Ipv6&Vy6)#Any*_wo3#u*n!5FK1@gF`izf6p z-edMN2>*qC-h?vFe$FMH=;!DeQ0P*o(a%3p8vVSH@-bhe@8941TDBZ^Mrpj85tJrh zTn_ugydxcC$xk7lFq)q-557$1ab5B=DC~>elZ|kjMSrTiD-t zm95_evfn4r7iYi!i~5ItzpVQ$)9Ck0y5GMA#dk=ikw5zmudnD6`T^M^Bi{f*pa;&JRH^ zd!?-Y%oY=eE?*=Ze&`4&*ZsIz26ewlWzgS8O&oQiErZ4!#h+de}Gze;Mn_fLsTw zGM@w=eBR=RKOxMQt;$GU;~e}UohRS}K7z5J_%t5}sh(FGkzCh>kSO@ly3@vI+*mF7Rs=kcf z4^zE=Lp`&vZt)*u@LgC-F_&>pL~F7LzI?TBL*xmH!-JUXay>`BnDg=%=`-rN?iFT= zg{N**G0V<^Y)$6KB{F8&=^Ln}m}RF3&dcGe5v z91Hbkp`IJB_c5O#EJ+U4X`=)&tA_+QWbp{w=+%|8-(^%?M|y}qrF zlU(?}i#F*Dlk`txvUjp$O#0_%x-ceeyQ7b*GfWzL*xRWX#t8A*!6NW@R16%HHbLj0 zbY`pHQQ_xr%@Np54ikkBc2d0vWBq%;cg(pSjT60xl4nI&J1C7a-!EnLJ6Lh{j@S4z z%Mv7e(fQ7EZ7K5x@%+pUKK%1PPxkL+t8bxQula%ZZt|ReW}&8&G%eB;>z$o<{=GDx z9YJ1s#zip>`4us~|KM`yS^7)(KhCx<}>YSX^oQ)fwh z)^>z^2F{E~S9?Qqaz0ue_N`_Xtp$C(0I(*Q`GK**{}X zIUzHf_mnM#v-I(!^1BAK|F`8_-|tZE+#+!JLp~3IjrjdqxouYHy;o4872A9{Q5RNZfnX= z?rio>VXP@eoZnKE@vC(N=QUH5{#&MGesLQ8gwFnhd^P4NeLjsdRi38;-_;N z1E(`uIx8KA*i8G{oxUuU@$WcXQa{}a2#W4o1=3TvKPdeWG_p>OZrmi_jPKM*8IoSca}&WkCQ#o`j0ak zc_w4jt=4(N)ygOE{DMz;Fi3k&M_V_eJjD{T)b|`lMiF<6QhV3>GMlL1pf>v&RQ464 zyv4rEM>Rbf&%JYydL|oOg}hNR!i%XP@( zz8pbc!e(DuE|+}?piFL#4Jd5%E!4wV*|$KQ{S?$5`gss}q)VAT>dX9u(vbNqQPj1q z2ZNVq7UBF?>X2=8@QMuamt_Ou)G)?*cpmJdT-gAPJC!d$T{=6q)fHD}zDjjbUY-*g z_EE0m$LDbtDc2eB%jCP0mk5Wg z9|e_j0d+T-Wl(n)l|kLdOdNH;PB`km4jPxA*>4;;XIvrmW}Lyrptk{vmj;V7&x21t z?O(9pCCmp5=^^?q>gSPXU(@a9ZnPJ6J9l$k?<12k&+-@zPSWfBC7D~PA6T!KVl1S6 z!*|h`1S$Tu4Ru=b55Np5yuOohC~E3VHNBJeh~{I6C8_7@X2{ zmWg-VDi7ytGOu6d{Tz98#-w;IRC!{ftT%+b+!>a*G_&_&r#>&uy!5;L8CJjC%c{LU z>xBAFeUl)WlDW!v-#lzLYWzCC~kfwg=d)fDenAbVqQAlDK9!GZSU?Df>S~Kn!YWVjt5uwq&kD037oyjXI&~u z@ampKqL@D4R1)mPZ|`b@sw=Cjs;jGOs%vXPHQ}1F zn(~^8n#!80n(CUGn%Y{3Sc~Rs!MYaJY5~c?!T<92S%kytRu(JS+1){xt<+d`UF%Y7 z6Fs=wp)%dq-I1ufU0$#fl@D{cPtBJ#qI`SV-*;%gIW-1*U#SYMp8 z#onIyywbdpm(Gi)I&puEGIEI4`fxhY8(eT}@Q#J6tVQ=WN1K$qt79F#WU|uEd%I&@ zxD}!|jq&fIn<9z{A(JN}ZKONZD=T&-9SGk<=L^Nqpw*t&$& zeMzt+6Gg-rVWyu7yg{bIOZnM{Q2E|z3pmYRWtaV#t%+GiX>+) z7Hd5d!6?;DPQaL*bXk`0_M<(iKHR9&*PZvF#F+h|cRhFi>*Zg)>_o|L#trl5^ZiSv zM5GV16k7@zlZ!jg*@;;v&slj>d!F)*6!us)C!t1O&I@~mwnR=)*$dNc;=-UFS63cjuxU`4QLSbe$X1w&7iA51rAErgBF8s0o??;0Q_5i41S<5{A6^r19bUM zM@Kh<&cP;O7ibOW0nirEW1t5>C*ce3r$I|VXS_N(+5ox{G!1$d^hwZ)gQKInK^s61 zfp&nN0qqAZD#YDEpdrvKXfvpI4f27`0DTg)26Q)Q3+N%xO`vB$p97sf5qbly0X+`d z09yDu^aMHwbQ5RAcY%gLkAdR%(V`GvjMxHN0=g5l z9&`wFJ?Kf$&7g%ChZjJLL9?Lspl3llK#SfO9o-1J0Q5P~RiOJoJ3s|4Ye|FF;NYYE z7o(#spwD3ww+XZeUohDYS^_!^<=R0jK%WC`20aX#20aV96|^WjI{E@=1L!``IY%%) zpc_HYf*t~$feq1F&_$*pc`>muoHAQ=n&}ZpvOT^fC|WS26P(e z5^O}pWFhv04uB5*Z|D_t!EaC=bQS1+lD zW7wdc{14dE6zKIoVNamNzk__Bn?N^%J_lNeaz$@J-=NK)%RyfRZ3oSQ_Jf`QeG;_z zH2MR29CQfuG-xyU(1WCWd>?KUf%Wh8T{8*0Z6MR}@7PPw6Xh;LFcx0guWlv98^hA-rO-V5gWzOPX5Wa=VqfF8J!GY>;#=o=Z`(~;? z)luJ4_3^t5u>kok-@_ckXYS{HZ~jusLHzGW{v`0Hvcx}%9KzGUi-1#Ggf9b5WvIOw zz@>h*-fq|YDE|fImmoi_>V>wAe|p>pjP?#7zaROeFXFpg^F0Q93-A_&%kj8d*9!s* z;K-p6{n(`PCErC)1U|&$MRJlZJ5c6DD*xU|#6PmF@aYMQo*2KD%aM!?bbK)g`$Kt@ zk!|_GiIhV5bkBAR)&)7B~x}vrBew3+EWuz?iS{BNm6hNPlPoG(isF7cS{BDnY z(px?9JCJYcka)ELZ}(_7i2SpVs~`EK;{fjd!y?r`g^Ob&vJ|70Y)uTPirum&1iQ$9ExL+hT6* zr}%sjcu@1Bn2BwL+M~Fg@)xN5qC3zYl^q0r47m3DY(qA`e+*@65M%FBb>;ejMVq=J z*U$i5?g8XisC>CDtT1GrgZwP=X&lklTpY6i_%YzqHNFHKDJGR&A|G~TtTTu5f#^Wifsbl7Z=1qLgkW9ZsK87Li zs^l~1+cy2_D;GU+h5xAHL$YrNpC=(>jp9>O4=s`GgTQxTzuTg4sbh2P%Od|Y@~JH8 z$h2{SMn`>9w)g^vePX*WaMCAE_@Fg_*VG4I_luTp#HWXRf#ZI0+E;?l$NZQKlpP7c z&-nt!{Ng!Z;DBH3@|C=ZpQHKPWcJh$vX=y&^ojaO_>~1%D|iWLbKp6jNC$TNP)D^@ zxFk?7?pH;KIsco{0&FALk0TDd#);j&62w9;_;*2BDA$ChvxQ>6F97d<$X9~1ks*KJ zsfpsWKd^D4*jP|^bf{4HafkP9;;XnZH@_o%|B_}3| z{zBSgfbG1^ezd!*An@D-ai}1$d4f1zP;z#>I2{ONCx|D<1@=!6+sBpco*>SQJBtxR zl`9YU0yy4QTP{r-}T1>%q&W{a%StS_*8yx8au42*|$M0?f zhsQ(4ze8e2+M%G0)^fYd$@krn}?KG~ESnrsF!zzFS z`Mb=Q^L@=aXE|IUJ+wy9qni`>4vc(u>vKNFhve#-mm8j4J_r%z!|lIUr@4QB998{; z-X-)Wou>0pdPa2`o=rX{b$Y8-^oUO5nDhVX6V!_QAF9;Odf>kwSJTZiN#*l>{1-Y% zd|&^C*5mSguRo_L?y52V;m=;o4;J6m+Sirt3x>n^^A@4G;XauRf26FeG*oe;hM9vm zEr9pv)^=}}DiHqM-^;V(1@gSl#OO2qbqt>GW?lhiKhJYJK0fCU?Dz!1^Tdv0s_FS< z$0rJ&$9DW8!SmgY!@D>g3JMh9o4pssj@q+`cR@tGpF zI`pjYvExPSpPM|)e-|$(y4@hCUtA&>=k-UGA8T(4A8S8z&)M$9qR3&l%%{*{Zxnu< zOa38;{I_ZOo%lkH%NJny%#YIBRl@0~no)rC;EZz~0PaK7!1lmar}&Ju&vml=SbUr2 z&+!(L@=<)o+W+&&^|{OoRep-t?rINtIW>E+A0OQGsrXD5(;fQ%nQS+YbAL~2JgCbv zjyroH=VVdrz}5I(B96a@B~kP;T|VR}KS$#=4jjM1ko+SKyiViGHO}$PJsNLt;O!b; z<-pfzyv2ckOyXCIkoE&e%17xfk84YoxZ~5WbH`76;Dy(_mk)X1PkG?`Jn$19c=HYJ?H=&J1I6y;gC6(-54^zx z-{gVs^uUKa@Dm<*;f?O{hdl6A9yotbow>1{Z1E_++XFx3fuHuki}e22*=~sk9`V4N zJ@9S^K2bI_HvZxM@_yVY5AV+zXFj}-x8swAbKj2NT}nUGq5XM_uE6a&_x+5Yb;!^7 zjGMVdMHyf2f#2_eZ}7l(df*2&lfvz`VkKKVLnIUa|Na6X=2b3 zuPXei+~4KmRun!(%(;&dMW-TOJl8sY{0@70UdI`Sc=F+O{G=|=IIrVp960M?fup~3 zAP@DI@j}g?%b%q{&UkLszaLCVi)`7GAOn2;4xO}k6u205K zSG(iQv`IG}F2CIaKj49%@W6{}4d(dB{0BVnX8xk9uEymzdEn1EaE{-0>%Tw9(1G*(DstdFzot8Io?k%+&hx8Sv*mhpWK{%p@@mMIP`n$de;hvYx`y_3^_^54zncB#Jt=a7dIj40}L zj>P3RIL;^Q&@S#I5l)=Axy_4vP@cXe<2)CA0JyoYr&9E6ko-@LI?pHnQse9O-<4FQ z*{;T(>wXF4XG1>&K~=I|SNI2w^S-rM<3H3muge@qz2U)!zFSKC3uh??x$Sg-v^@4H zLHWy2p2uB&&kDt^M|tAI`zapBdo|AcK9=)Qjk6t2(oH?5ao(p-)A(VH^ZtwZFT{H| zDZk!dGkSxGHz<$5lV0%kzGg+x<6<^Z5Y#=bOhXdDsuM zYeu&Lca!G>x;*c@S^mc~&gVAVF8vj4H$Gp*x-bRjmi%6*f39kne)mH9VSlwm%k#I> zg$Sa*&hzjeqx=-a75rWRYL^eb?cmz(8O@*1Jy`xl6I8n#XEtj-ap1GSpZA-*JUCP<^m?ITF;|!8^S8q~qXD>^ zK9j(ofj#iK-w$>9XEdMUhysc={wkvIZ&^Yg#f)W+tXBv0WD7S=b5}NT#qj%NdJGMV!(2))VR|R{M>{8KcT#v{G~;TKcDY$yM^$#G>^7i zt=iqBL^Z+k;NDb;JLm5y5B`_JFr*zi;;7lcslU_ptK=7T zPv%K{Ot-{x&BwW(epcgr9?tstBk}RW`CV@3rmym+Re`%ceL2M`Euwj5Hj(KJSCwcgsmhJgN8t3;- zJm25a@ehBWrCkfUPM3GCgWvIJ_s789^maAu)lJT74}2|f8uur4fJ5KersrcCe_h){ zzfa+x2TuLv_in7WztuRuzX+=0;)KTeeJlOGlAiG}Y~sW3*A6LI%mq$<)j96B0C(%} zr!*fv_o&c(z9RXIjT^tA%kz0V%u+tT(Kw%zaK9+@bo2A$fRp@u4$t;hrg1*+4Ql?& zG|uNIt2F)rjXVAJGaBdj7i@>W);Pasl)qO5uc`3wBoDv;;&wlvaejZdUbnl|qx@lw zJLA|Humj@H?>m_PYK`-I9G3H|z}?328@fE7ukOeQ2b}yZe{YB9=`P@I^87&a*%(oLUrQi< zKJUT%Dw3by%Ma*z@ga@#`=biY|2d8Gd#j+vUj^eaz zG|uNs9lHGOz}?zy1!J7ejknD zkk2ZOp9rcn;~g63^Y%$9TWr?2bN~BIjr03Z9(Oci>%X~heaXx=zdwy2qPJjFF8h6h3;4JrXnFpNY;rA~sLOl%{=l5AP8jmxs<5(v+CfhP!8Ctw}2#TO;PI7l4z1 z4`mT(M?+qi`6}`&V<$0*V*~7ycj2! z!YxtBw5@0#0k|S8O&82q_cf*K!?oSXL_G0OvKRMDrEsfMPhUK(v&!`iFsU9eS);(J zP|CKUz@+1%(|~W9A0$S;uXKKys;To5l`GD8(9ekZss!HAL*RYOK6=BO#*ZxTL zBx4=P591Ox+%p!#ML})Q4QYVVp=456%j)l3w6Gpk`dY0z%et>h>Lk3*e$|#zC&aO= zHTq5*Trrbem$16mkpyL-d`4$qI6zo>oDc#C&x$Slz z$kQwD3X6*T6;Ui~S?|Lz$xci52&x&&ER?Tga569bk-WxMEHlg0XfsMg(TKIQap4_N zE4p%tWg)d}%S`PzKsv8MZaIxGYLK&tLUdrEdCTyn=4R;)J7W*ip4C*@lv2HqE#rFkPj(r5Q#e z%j)YEEnchR5jDATy2DXe;FAKGx4d4ZCYyD43byX78=^|aMBE?u`S8ojgGYDDYds-8q=3dYz& zvo(Qhw#W_PTwBaK->F3Cj$(c7cZ z#^#XK=vQYwbu-9}{h{ zbWAI{(z4*s9;6Gv_!dX!2)T3u+KfgqNO$O7^*Dz70xyPKTvm5`V^cYJMwfI$-y~aY z?!vNi+*hWDrWW466CFt>);aq+=EBLv;kx?PaFqT*zia?GjgVE6^6buoe1zg`m6e98 z?SfR$4Q$bdbxk2iSa&BpU|X`w>g!F=dIonGUu(tNv3kXl9S$B)VTjb+2Va)%aj^j} z9YZtF3#_n#4LBt4#*-IZhReJ9IxT6GEOi{XqG1>?}B06Kq zE(};xx&l|Ub=1YdB^+;$A)xAsCDXliaZD6o<#4;nxRt^xo``kUVU-A3(WWZP6c-jB zUmsJ;9;Ty}SRYSx(~2K~FJHK*&I*^7lWl}edo43B1eE3q+Zj6&d4u9b!lk>?1wltV zTqyGHrWjkHeH9BMD$6aoD(E3u-(3^oFwG*h0BBcf>ZOM7SCnfzhK5#kV_LzJ$))J_ zs9KK5N0JM&V!d?ptc$~;$_O^v5^4A%3aAiF(m?lGm}%15ABaZRHN+pl3Pa_RYcTw( z&Dz{Z>b12Aw>Dp}spN+cein|!YU@o|?FbG#5)O~6;xhYWX}&vOpH09tJ~>yU{UMI0 z*fU|TkJ{B_pX=$8Wo68;W!%c_){mwb**#f-y@{~aM=RnGX$koWSt%pUeC(lT_67P| z4C|OxuPI%dYtJc?lIKD@2B|yaSpLdw)3>xNESB6;idd!;LCgB}79y736zLMT1h2!c z$t|8i7)EaS+~G=@5w0|)DP~8!m%HhW7hO=h(bu*ik<38M;qiON=adO-F#5wvZJ{W%g-^= zT|C$2?6v59QeNF&cRTH!@T@~O%W$7N?oPM#Rqm^LyJ4(yC(_o@VDp!* zYO-uwecR+ydokKe)W|;(f%7AE`anyw`!eX5o9DY{#hPo|Pbu55?b=-r8{7hJ8G)W_ z=U$m#3e{Pg3Yl?ol}y_P*lNCGF`wq#w^E(0Ci^3??upIi_X`uQ$Cg*t?Xt2+lKHZD1!WxHm^JkUDN}$3|Ojx;cRjGZFii#0N z4F{p{Fkww4dkRQ)wgjhhp-R_njgwg!RVZp52Jg73Qcd z7mjU>gT}l|ybuQqPPqdm-l}jYd0~GQC+B1gPp@KqxnH;dCw?c+Xp~Cdr6eKhNq*uH zulzKrQh(=0hpkv}$2Dl1llfPmDl5zu=L>?n5v8Z*RPg&TdSJy-MLr_*DbkK?OqQ#5x#)%F(R!S|p8m{SPRVYCE z9CKDZ)^G92wbqei|B>^xf6o4cJTBfPIEH~DX)UR_NVvS`g3vj~tB)2;pK9#Y938%( zO}H@`rFA*ZQyd4vQ5=*agzQ$Y+m$hf!|C=U|Jk@IiqsL@eE3kiL4BYPfG2um1_|ID?>T7y4BX2v|W@H+ppM@lOLY>o~p=)INH zN^Zjdu`gsjldm{0V69Ob2AXf~vyC))p#fWRz5Nv?9a3U`I$lY!eZ$?^mL8XVV(v6< zjIE!?Ssd0+Z zbiZy8Ka0YxU-|nQ`TJ#eYnyP`tQP*Fj8S=e%O!;0+ zs!w&C^*;@abVBmU2j43kLgSJ9hdpA{utYi57a)_=ijq3 z#cjy8$Jze39rgJ>K&Cl+(p;SF4?63wQ3d(_z%3-4@i>y=Ao7SOUByff-y^u23>%Mg zyqxVHLK!l3?xwSTF)=Y7uFv!s^6*okTz$T;Fss|=a?FC$Oiv<%`o!(?_oI*N`Vp?E zDc588ZG2$gLKy$PxLALIIH(7f=Lgqky^KfWX8U|k;_@!l0)Hi0EsM58G&~HfG>VNh{Rca;+sw+8?;{O7xLVdpg diff --git a/test/test1.log b/test/test1.log new file mode 100644 index 0000000..9720aae --- /dev/null +++ b/test/test1.log @@ -0,0 +1,1223 @@ +# 测试: 申请1024次6字节 + 6字节对齐成8字节。如果第1025次申请,就会找新的span + 预期:log中只有两个goto os for mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/central_cache.cc][45] central_cache::get_non_empty_span() cannot find non-null span in cc, goto pc for mem +[DEBUG][src/central_cache.cc][52] central_cache::get_non_empty_span() call page_cache::get_instance()->new_span() +[DEBUG][src/page_cache.cc][43] page_cache::new_span() cannot find span, goto os for mem +[DEBUG][src/page_cache.cc][37] page_cache::new_span() have span, return +[DEBUG][src/central_cache.cc][58] central_cache::get_non_empty_span() get new span success +[DEBUG][src/central_cache.cc][70] central_cache::get_non_empty_span() cut span +[DEBUG][src/thread_cache.cc][47] actual_n:1 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:2 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:3 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:4 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:5 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:6 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:7 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:8 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:9 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:10 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:11 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:12 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:13 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:14 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:15 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:16 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:17 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:18 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:19 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:20 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:21 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:22 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:23 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:24 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:25 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:26 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:27 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:28 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:29 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:30 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:31 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:32 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:33 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:34 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:35 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:36 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:37 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:38 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:39 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:40 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:41 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:42 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:43 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:44 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/thread_cache.cc][47] actual_n:34 +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][./include/tcmalloc.hpp][14] tcmalloc find tc from mem +[DEBUG][src/thread_cache.cc][16] thread_cache::allocate call thread_cache::fetch_from_central_cache +[DEBUG][src/thread_cache.cc][43] thread_cache::fetch_from_central_cache call central_cache::get_instance()->fetch_range_obj() +[DEBUG][src/central_cache.cc][12] central_cache::fetch_range_obj() call central_cache::get_non_empty_span() +[DEBUG][src/central_cache.cc][45] central_cache::get_non_empty_span() cannot find non-null span in cc, goto pc for mem +[DEBUG][src/central_cache.cc][52] central_cache::get_non_empty_span() call page_cache::get_instance()->new_span() +[DEBUG][src/page_cache.cc][37] page_cache::new_span() have span, return +[DEBUG][src/central_cache.cc][58] central_cache::get_non_empty_span() get new span success +[DEBUG][src/central_cache.cc][70] central_cache::get_non_empty_span() cut span +[DEBUG][src/thread_cache.cc][47] actual_n:46 diff --git a/unit_test.cc b/unit_test.cc index 04ce9e3..c9aba6b 100644 --- a/unit_test.cc +++ b/unit_test.cc @@ -17,7 +17,7 @@ void tls_test() { t2.join(); } -void test_alloc() { +void test_alloc1() { std::cout << "call tcmalloc(1)" << std::endl; void* ptr = tcmalloc(8 * 1024); std::cout << "call tcmalloc(2)" << std::endl; @@ -34,7 +34,14 @@ void test_alloc() { ptr = tcmalloc(1); } +void test_alloc2() { + for (size_t i = 0; i < 1024; ++i) { + void* p1 = tcmalloc(6); + } + void* p2 = tcmalloc(6); // 这一次一定会找新的span +} + int main() { - test_alloc(); + test_alloc2(); return 0; } \ No newline at end of file From 32c3d8506c96e4a63f7ffe73ea38b979739e415f Mon Sep 17 00:00:00 2001 From: Yufccode Date: Tue, 7 May 2024 19:07:08 +0800 Subject: [PATCH 4/5] feat page_cache free part, still with bugs --- README.md | 72 ++++++++++++++++++++++++++++++++++++++++++- debug | Bin 0 -> 177752 bytes include/common.hpp | 14 +++++++-- include/log.hpp | 35 +++++++++++++++++++-- makefile | 6 ++-- out | Bin 0 -> 173584 bytes src/central_cache.cc | 7 +++++ src/page_cache.cc | 65 +++++++++++++++++++++++++++++++++++--- src/thread_cache.cc | 7 +++++ unit_test.cc | 29 ++++++++++++++++- 10 files changed, 221 insertions(+), 14 deletions(-) create mode 100755 debug create mode 100755 out diff --git a/README.md b/README.md index 673ed55..2ffde27 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ - [内存申请流程联调](#内存申请流程联调) - [thread\_cache内存释放](#thread_cache内存释放) - [central\_cache内存释放](#central_cache内存释放) + - [page\_cache内存释放](#page_cache内存释放) *** @@ -1110,4 +1111,73 @@ void central_cache::release_list_to_spans(void* start, size_t size) { 细节在注释里面写的很清楚了。 -要注意,调用pc的接口的时候,就记得把桶锁解掉。 \ No newline at end of file +要注意,调用pc的接口的时候,就记得把桶锁解掉。 + +## page_cache内存释放 + +就是这个函数。 + +```cpp +void page_cache::release_span_to_page(span* s) { + // 对span前后对页尝试进行合并,缓解内存碎片问题 +} +``` + +然后刚才的map可以帮助我们查找前后的page。 + +然后我们前后找的时候,要区分这个页是不是在centralCache上的,如果在cc上,那就不能合并。 + +然后这个判断不能用use_count==0这个判断条件。有可能这个span刚从pc拿过来,还没给别人的时候,use_count就是0,这个span,pc是不能回收合并的。 + +所以可以给span添加一个参数is_use就行了。 + +```cpp +// 管理大块内存 +class span { +public: + PAGE_ID __page_id; // 大块内存起始页的页号 + size_t __n = 0; // 页的数量 + // 双向链表结构 + span* __next = nullptr; + span* __prev = nullptr; + size_t __use_count = 0; // 切成段小块内存,被分配给threadCache的计数器 + void* __free_list = nullptr; // 切好的小块内存的自由链表 + bool is_use = false; // 是否在被使用 +}; +``` + +然后cc.cc这里改一下,拿到之后改成true就行。 + +cc.cc +```cpp + page_cache::get_instance()->__page_mtx.lock(); + span* cur_span = page_cache::get_instance()->new_span(size_class::num_move_page(size)); + cur_span->is_use = true; // 表示已经被使用 + page_cache::get_instance()->__page_mtx.unlock(); +``` + + +然后继续写这个逻辑: + +page_cache.cc +```cpp +void page_cache::release_span_to_page(span* s) { + // 对span前后对页尝试进行合并,缓解内存碎片问题 + PAGE_ID prev_id = s->__page_id - 1; // 前一块span的id一定是当前span的id-1 + // 拿到id如何找span: 之前写好的map能拿到吗? +} +``` + +现在的问题是,之前的map能拿到吗?还拿不到,因为我们之前的map只记录了分给cc的span的映射,没有存留在pc那些,没有分出去的映射。 +所以我们要在`span* page_cache::new_span(size_t k) {`里面添加一下,留在pagecache那些块的映射。 + +```cpp + // 存储n_span的首尾页号跟n_span的映射,方便pc回收内存时进行合并查找 + __id_span_map[n_span->__page_id] = n_span; + __id_span_map[n_span->__page_id + n_span->__n - 1] = n_span; +``` + +为什么这里不用循环存储呢? + +因为这里的pc的内存只是被span挂起来啊,不会被切啊,所以知道地址就了啊! +给cc的那些,会被切开变成很多固定大小的内存块啊!所以这里不用循环存。 \ No newline at end of file diff --git a/debug b/debug new file mode 100755 index 0000000000000000000000000000000000000000..d8935fa4f584392453dff2819f45a50e891633a3 GIT binary patch literal 177752 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 literal 0 HcmV?d00001 diff --git a/include/common.hpp b/include/common.hpp index d9b9dd6..61fdab5 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -8,6 +8,11 @@ #include #include +#ifdef PROJECT_DEBUG +#include "log.hpp" +#include +#endif + #if defined(_WIN32) || defined(_WIN64) #include #elif defined(__aarch64__) // ... @@ -70,9 +75,13 @@ class free_list { return obj; } void pop(void*& start, void*& end, size_t n) { - // 这里是输出参数了 - assert(n >= __size); +// 这里是输出参数了 +#ifdef PROJECT_DEBUG + LOG(DEBUG) << "call here" << std::endl; +#endif + assert(n <= __size); start = __free_list_ptr; + end = start; // debug 20240507 miss this for (size_t i = 0; i < n - 1; i++) end = free_list::__next_obj(end); __free_list_ptr = free_list::__next_obj(end); @@ -178,6 +187,7 @@ class span { span* __prev = nullptr; size_t __use_count = 0; // 切成段小块内存,被分配给threadCache的计数器 void* __free_list = nullptr; // 切好的小块内存的自由链表 + bool __is_use = false; // 是否在被使用 }; // 带头双向循环链表 diff --git a/include/log.hpp b/include/log.hpp index 39cf46b..9137379 100644 --- a/include/log.hpp +++ b/include/log.hpp @@ -4,6 +4,7 @@ #define __YUFC_LOG__ #include +#include #include enum STATUES // 日志等级 @@ -14,12 +15,40 @@ enum STATUES // 日志等级 ERROR, FATAL }; + +// 定义颜色代码 +#define RESET "\033[0m" +#define RED "\033[1;31m" // 加粗红色 +#define GREEN "\033[1;32m" // 加粗绿色 +#define YELLOW "\033[1;33m" // 加粗黄色 +#define BLUE "\033[1;34m" // 加粗蓝色 +#define MAGENTA "\033[1;35m" // 加粗洋红 + +// 根据日志等级获取相应颜色 +inline const char* GetColor(const std::string& level) { + std::map m = { { "INFO", 0 }, { "DEBUG", 1 }, { "WARNING", 2 }, { "ERROR", 3 }, { "FATAL", 4 } }; + switch (m[level]) { + case INFO: + return BLUE; + case DEBUG: + return GREEN; + case WARNING: + return YELLOW; + case ERROR: + return MAGENTA; + case FATAL: + return RED; + default: + return RESET; + } +} + // LOG() << "message" inline std::ostream& Log(const std::string& level, const std::string& file_name, int line) { // 添加日志等级 - std::string message = "["; - message += level; - message += "]"; + std::string levelTag = std::string("[") + level + "]"; + std::string coloredLevelTag = std::string(GetColor(level)) + levelTag + RESET; + std::string message = coloredLevelTag; // 添加报错文件名称 message += "["; message += file_name; diff --git a/makefile b/makefile index bdce528..f1892c4 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,7 @@ -test.out: *.cc ./src/*.cc +out: *.cc ./src/*.cc + g++ -o $@ $^ -std=c++11 -lpthread +debug: *.cc ./src/*.cc g++ -o $@ $^ -std=c++11 -lpthread -DPROJECT_DEBUG .PHONY:clean clean: - rm -f test.out \ No newline at end of file + rm -f out debug \ No newline at end of file diff --git a/out b/out new file mode 100755 index 0000000000000000000000000000000000000000..7dbaad6d49786153633b27efd586e891314e9b80 GIT binary patch literal 173584 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 a(WqRaGw~zs`S~BQwfZ$ySRZiy4E{eK^lWDU literal 0 HcmV?d00001 diff --git a/src/central_cache.cc b/src/central_cache.cc index d696421..92230e1 100644 --- a/src/central_cache.cc +++ b/src/central_cache.cc @@ -53,6 +53,7 @@ span* central_cache::get_non_empty_span(span_list& list, size_t size) { #endif page_cache::get_instance()->__page_mtx.lock(); span* cur_span = page_cache::get_instance()->new_span(size_class::num_move_page(size)); + cur_span->__is_use = true; // 表示已经被使用 page_cache::get_instance()->__page_mtx.unlock(); #ifdef PROJECT_DEBUG LOG(DEBUG) << "central_cache::get_non_empty_span() get new span success" << std::endl; @@ -96,7 +97,13 @@ void central_cache::release_list_to_spans(void* start, size_t size) { // 说明这个span切分出去的所有小块都回来了 // 归还给pagecache // 1. 把这一页从cc的这个桶的spanlist中拿掉 + // #ifdef PROJECT_DEBUG + // LOG(DEBUG) << "***" << std::endl; + // #endif __span_lists[index].erase(cur_span); // 从桶里面拿走 + // #ifdef PROJECT_DEBUG + // LOG(DEBUG) << "after ***" << std::endl; + // #endif // 2. 此时不用管这个span的freelist了,因为这些内存本来就是span初始地址后面的,然后顺序也是乱的,直接置空即可 // (这里还不太理解) cur_span->__free_list = nullptr; diff --git a/src/page_cache.cc b/src/page_cache.cc index 289cbe4..1a0d8b0 100644 --- a/src/page_cache.cc +++ b/src/page_cache.cc @@ -8,15 +8,27 @@ page_cache page_cache::__s_inst; span* page_cache::new_span(size_t k) { assert(k > 0 && k < PAGES_NUM); // 先检查第k个桶是否有span + // #ifdef PROJECT_DEBUG + // LOG(DEBUG) << "before ***" << std::endl; + // #endif if (!__span_lists[k].empty()) - return __span_lists->pop_front(); + return __span_lists[k].pop_front(); // ? __span_lists->pop_front(); + // #ifdef PROJECT_DEBUG + // LOG(DEBUG) << "after ***" << std::endl; + // #endif // 第k个桶是空的->去检查后面的桶里面有无span,如果有,可以把它进行切分 for (size_t i = k + 1; i < PAGES_NUM; i++) { if (!__span_lists[i].empty()) { - // 可以开始切了 - // 假设这个页是n页的,需要的是k页的 - // 1. 从__span_lists中拿下来 2. 切开 3. 一个返回给cc 4. 另一个挂到 n-k 号桶里面去 +// 可以开始切了 +// 假设这个页是n页的,需要的是k页的 +// 1. 从__span_lists中拿下来 2. 切开 3. 一个返回给cc 4. 另一个挂到 n-k 号桶里面去 +#ifdef PROJECT_DEBUG + LOG(DEBUG) << "before ***" << std::endl; +#endif span* n_span = __span_lists[i].pop_front(); +#ifdef PROJECT_DEBUG + LOG(DEBUG) << "after ***" << std::endl; +#endif span* k_span = new span; // 在n_span头部切除k页下来 k_span->__page_id = n_span->__page_id; // <1> @@ -33,6 +45,9 @@ span* page_cache::new_span(size_t k) { */ // 剩下的挂到相应位置 __span_lists[n_span->__n].push_front(n_span); + // 存储n_span的首尾页号跟n_span的映射,方便pc回收内存时进行合并查找 + __id_span_map[n_span->__page_id] = n_span; + __id_span_map[n_span->__page_id + n_span->__n - 1] = n_span; // 这里记录映射(简历id和span的映射,方便cc回收小块内存时,查找对应的span) for (PAGE_ID j = 0; j < k_span->__n; j++) { __id_span_map[k_span->__page_id + j] = k_span; @@ -62,10 +77,50 @@ span* page_cache::map_obj_to_span(void* obj) { auto ret = __id_span_map.find(id); if (ret != __id_span_map.end()) return ret->second; - LOG(FATAL); + LOG(FATAL) << std::endl; assert(false); return nullptr; } void page_cache::release_span_to_page(span* s) { + // 对span前后对页尝试进行合并,缓解内存碎片问题 + while (true) { + PAGE_ID prev_id = s->__page_id - 1; // 前一块span的id一定是当前span的id-1 + // 拿到id如何找span: 之前写好的map能拿到吗? + // 找到了,如果isuse是false,就能合并了(向前合并+向后合并) + // 如果遇到了合并大小超过了128页了,也要停止了 + auto ret = __id_span_map.find(prev_id); + if (ret == __id_span_map.end()) // 前面的页号没有了,不合并了 + break; + span* prev_span = ret->second; + if (prev_span->__is_use == true) // 前面相邻页的span在使用,不合并了 + break; + if (prev_span->__n + s->__n > PAGES_NUM - 1) // 合并出超过128页的span没办法管理,不合并了 + break; + s->__page_id = prev_span->__page_id; + s->__n += prev_span->__n; + __span_lists[prev_span->__n].erase(prev_span); // 防止野指针,删掉 + delete prev_span; // 删掉这个span + } // 向前合并的逻辑 while end; + while (true) { + PAGE_ID next_id = s->__page_id + s->__n - 1; // 注意这里的页号是+n-1了 + auto ret = __id_span_map.find(next_id); + if (ret == __id_span_map.end()) // 后面的页号没有了 + break; + span* next_span = ret->second; + if (next_span->__is_use == true) // 后面相邻页的span在使用,不合并了 + break; + if (next_span->__n + s->__n > PAGES_NUM - 1) // 合并出超过128页的span没办法管理,不合并了 + break; + s->__page_id; // 起始页号不用变了,因为是向后合并 + s->__n += next_span->__n; + __span_lists[next_span->__n].erase(next_span); // 防止野指针,删掉 + delete next_span; + } + // 已经合并完成了,把东西挂起来 + __span_lists[s->__n].push_front(s); + s->__is_use = false; + // 处理一下映射,方便别人找到我 + __id_span_map[s->__page_id] = s; + __id_span_map[s->__page_id + s->__n - 1] = s; } \ No newline at end of file diff --git a/src/thread_cache.cc b/src/thread_cache.cc index b046f5b..a0de15a 100644 --- a/src/thread_cache.cc +++ b/src/thread_cache.cc @@ -58,6 +58,10 @@ void thread_cache::deallocate(void* ptr, size_t size) { __free_lists[index].push(ptr); // 当链表长度大于一次批量申请的内存的时候,就开始还一段list给cc if (__free_lists[index].size() >= __free_lists[index].max_size()) { +#ifdef PROJECT_DEBUG + LOG(DEBUG) << __free_lists[index].size() << ":" << __free_lists[index].max_size() << std::endl; + LOG(DEBUG) << "call list_too_long" << std::endl; +#endif list_too_long(__free_lists[index], size); } } @@ -66,5 +70,8 @@ void thread_cache::list_too_long(free_list& list, size_t size) { void* start = nullptr; void* end = nullptr; list.pop(start, end, list.max_size()); + #ifdef PROJECT_DEBUG + LOG(DEBUG) << "list pop success -> call release_list_to_spans()" << std::endl; + #endif central_cache::get_instance()->release_list_to_spans(start, size); } \ No newline at end of file diff --git a/unit_test.cc b/unit_test.cc index c9aba6b..dcb04d3 100644 --- a/unit_test.cc +++ b/unit_test.cc @@ -2,7 +2,10 @@ #include "./include/tcmalloc.hpp" #include +#include +#include #include +#include void alloc1() { for (size_t i = 0; i < 5; i++) { @@ -41,7 +44,31 @@ void test_alloc2() { void* p2 = tcmalloc(6); // 这一次一定会找新的span } +void test_dealloc(int alloc_times = 10) { + // 创建随机数生成器 + std::random_device rd; + std::mt19937 gen(rd()); // 以随机设备作为种子 + std::uniform_int_distribution<> distrib(1, 127 * 1024); // 设置随机数分布范围1-127 + // 生成并输出随机数 + std::map s; + for (int i = 0; i < alloc_times; i++) { + int sz = distrib(gen); + s.insert({ tcmalloc(sz), sz }); // 申请随机值 + } + for (auto& e : s) { + tcfree(e.first, e.second); + } +} + +void test_multi_thread() { + std::thread t1(std::bind(test_dealloc, 200)); + // std::thread t2(std::bind(test_dealloc, 20)); + t1.join(); + // t2.join(); + std::cout << "run successful" << std::endl; +} + int main() { - test_alloc2(); + test_multi_thread(); return 0; } \ No newline at end of file From 38caa52a5a355c38618dc4bc0e1a1a42a5d380fb Mon Sep 17 00:00:00 2001 From: Yufccode Date: Wed, 8 May 2024 00:05:00 +0800 Subject: [PATCH 5/5] fix the bugs, The tcmalloc project is basically completed, but there are still many areas that need to be modified and optimized. --- README.md | 18 +++++++++++++++- debug | Bin 177752 -> 0 bytes include/common.hpp | 15 +++++++++++-- include/page_cache.hpp | 2 +- include/tcmalloc.hpp | 18 ++++++++++++++++ out | Bin 173584 -> 0 bytes src/page_cache.cc | 47 +++++++++++++++++++++++++++++------------ unit_test.cc | 13 ++++++++---- 8 files changed, 91 insertions(+), 22 deletions(-) delete mode 100755 debug delete mode 100755 out diff --git a/README.md b/README.md index 2ffde27..b369efd 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ - [thread\_cache内存释放](#thread_cache内存释放) - [central\_cache内存释放](#central_cache内存释放) - [page\_cache内存释放](#page_cache内存释放) + - [大于256k的情况](#大于256k的情况) + - [处理代码中`new`的问题](#处理代码中new的问题) *** @@ -1180,4 +1182,18 @@ void page_cache::release_span_to_page(span* s) { 为什么这里不用循环存储呢? 因为这里的pc的内存只是被span挂起来啊,不会被切啊,所以知道地址就了啊! -给cc的那些,会被切开变成很多固定大小的内存块啊!所以这里不用循环存。 \ No newline at end of file +给cc的那些,会被切开变成很多固定大小的内存块啊!所以这里不用循环存。 + +## 大于256k的情况 + +1. <=256kb -> 按照前面三层缓存的情况进行操作 +2. \>256kb的情况 + a. 128\*8k > size > 32\*8k这个情况: 还可以找pagecache + b. 否则直接找系统 + +然后这一部分就是有多处要改,不过都很简单很容易找到,大家可以直接看代码。处理完之后,测试一下申请大内存就行。 + + +## 处理代码中`new`的问题 + +代码中有些地方用了`new span`。这个就很不对。我们弄这个tcmalloc是用来替代malloc的,既然是替代,那我们的代码里面怎么能有`new`,`new`也是调用`malloc`的,所以我们要改一下。 \ No newline at end of file diff --git a/debug b/debug deleted file mode 100755 index d8935fa4f584392453dff2819f45a50e891633a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 177752 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 diff --git a/include/common.hpp b/include/common.hpp index 61fdab5..9b280f9 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -48,6 +48,17 @@ inline static void* system_alloc(size_t kpage) { return ptr; } +inline static void system_free(void* ptr, size_t size = 0) { + /** + * linux的munmap需要给大小 + */ +#if defined(_WIN32) || defined(_WIN64) + VirtualFree(ptr, 0, MEM_RELEASE); +#elif defined(__linux__) // ... + munmap(ptr, size); +#endif +} + // 管理切分好的小对象的自由链表 class free_list { private: @@ -116,8 +127,8 @@ class size_class { else if (size <= 256 * 1024) return __round_up(size, 8 * 1024); else { - assert(false); - return -1; + // 大内存 + return __round_up(size, 1 << PAGE_SHIFT); } } // 计算映射的哪一个自由链表桶 diff --git a/include/page_cache.hpp b/include/page_cache.hpp index c4aa545..092eaad 100644 --- a/include/page_cache.hpp +++ b/include/page_cache.hpp @@ -20,7 +20,7 @@ class page_cache { static page_cache* get_instance() { return &__s_inst; } span* map_obj_to_span(void* obj); // 释放空闲的span回到pc,并合并相邻的span - void release_span_to_page(span* s); + void release_span_to_page(span* s, size_t size = 0); public: // 获取一个K页的span span* new_span(size_t k); diff --git a/include/tcmalloc.hpp b/include/tcmalloc.hpp index d2da5b6..8d84bb0 100644 --- a/include/tcmalloc.hpp +++ b/include/tcmalloc.hpp @@ -4,9 +4,20 @@ #include "common.hpp" #include "log.hpp" +#include "page_cache.hpp" #include "thread_cache.hpp" static void* tcmalloc(size_t size) { + if (size > MAX_BYTES) { + // 处理申请大内存的情况 + size_t align_size = size_class::round_up(size); + size_t k_page = align_size >> PAGE_SHIFT; + page_cache::get_instance()->__page_mtx.lock(); + span* cur_span = page_cache::get_instance()->new_span(k_page); // 直接找pc + page_cache::get_instance()->__page_mtx.unlock(); + void* ptr = (void*)(cur_span->__page_id << PAGE_SHIFT); // span转化成地址 + return ptr; + } if (p_tls_thread_cache == nullptr) // 相当于单例 p_tls_thread_cache = new thread_cache; @@ -17,6 +28,13 @@ static void* tcmalloc(size_t size) { } static void tcfree(void* ptr, size_t size) { + if (size > MAX_BYTES) { + span* s = page_cache::get_instance()->map_obj_to_span(ptr); // 找到这个span + page_cache::get_instance()->__page_mtx.lock(); + page_cache::get_instance()->release_span_to_page(s, size); // 直接调用pc的 + page_cache::get_instance()->__page_mtx.unlock(); + return; + } assert(p_tls_thread_cache); p_tls_thread_cache->deallocate(ptr, size); } diff --git a/out b/out deleted file mode 100755 index 7dbaad6d49786153633b27efd586e891314e9b80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173584 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 a(WqRaGw~zs`S~BQwfZ$ySRZiy4E{eK^lWDU diff --git a/src/page_cache.cc b/src/page_cache.cc index 1a0d8b0..eafda69 100644 --- a/src/page_cache.cc +++ b/src/page_cache.cc @@ -6,29 +6,39 @@ page_cache page_cache::__s_inst; // cc向pc获取k页的span span* page_cache::new_span(size_t k) { - assert(k > 0 && k < PAGES_NUM); + assert(k > 0); + // 处理大内存情况 + if (k > PAGES_NUM - 1) { + void* ptr = system_alloc(k); + span* cur_span = new span; + cur_span->__page_id = (PAGE_ID)ptr >> PAGE_SHIFT; + cur_span->__n = k; + // map记录一下 + __id_span_map[cur_span->__page_id] = cur_span; + return cur_span; + } // 先检查第k个桶是否有span // #ifdef PROJECT_DEBUG // LOG(DEBUG) << "before ***" << std::endl; // #endif - if (!__span_lists[k].empty()) - return __span_lists[k].pop_front(); // ? __span_lists->pop_front(); + if (!__span_lists[k].empty()) { + span* s = __span_lists[k].pop_front(); // ? __span_lists->pop_front(); + // 建立id和span的映射,方便central cache回收小块内存时,查找对应的span + for (PAGE_ID i = 0; i < s->__n; ++i) { + __id_span_map[s->__page_id + i] = s; + } + return s; + } // #ifdef PROJECT_DEBUG // LOG(DEBUG) << "after ***" << std::endl; // #endif // 第k个桶是空的->去检查后面的桶里面有无span,如果有,可以把它进行切分 for (size_t i = k + 1; i < PAGES_NUM; i++) { if (!__span_lists[i].empty()) { -// 可以开始切了 -// 假设这个页是n页的,需要的是k页的 -// 1. 从__span_lists中拿下来 2. 切开 3. 一个返回给cc 4. 另一个挂到 n-k 号桶里面去 -#ifdef PROJECT_DEBUG - LOG(DEBUG) << "before ***" << std::endl; -#endif + // 可以开始切了 + // 假设这个页是n页的,需要的是k页的 + // 1. 从__span_lists中拿下来 2. 切开 3. 一个返回给cc 4. 另一个挂到 n-k 号桶里面去 span* n_span = __span_lists[i].pop_front(); -#ifdef PROJECT_DEBUG - LOG(DEBUG) << "after ***" << std::endl; -#endif span* k_span = new span; // 在n_span头部切除k页下来 k_span->__page_id = n_span->__page_id; // <1> @@ -82,7 +92,16 @@ span* page_cache::map_obj_to_span(void* obj) { return nullptr; } -void page_cache::release_span_to_page(span* s) { +void page_cache::release_span_to_page(span* s, size_t size) { + // 第二个参数是为了linux下一次释放大内存,需要大小 + // std::cout << s->__n << std::endl; // 33 + if (s->__n >= PAGES_NUM) { + // 处理大内存 + void* ptr = (void*)(s->__page_id << PAGE_SHIFT); + system_free(s, size); + delete s; + return; + } // 对span前后对页尝试进行合并,缓解内存碎片问题 while (true) { PAGE_ID prev_id = s->__page_id - 1; // 前一块span的id一定是当前span的id-1 @@ -103,7 +122,7 @@ void page_cache::release_span_to_page(span* s) { delete prev_span; // 删掉这个span } // 向前合并的逻辑 while end; while (true) { - PAGE_ID next_id = s->__page_id + s->__n - 1; // 注意这里的页号是+n-1了 + PAGE_ID next_id = s->__page_id + s->__n; // 注意这里的页号是+n了 auto ret = __id_span_map.find(next_id); if (ret == __id_span_map.end()) // 后面的页号没有了 break; diff --git a/unit_test.cc b/unit_test.cc index dcb04d3..52a9dbe 100644 --- a/unit_test.cc +++ b/unit_test.cc @@ -1,11 +1,11 @@ #include "./include/tcmalloc.hpp" +#include #include #include #include #include -#include void alloc1() { for (size_t i = 0; i < 5; i++) { @@ -48,7 +48,7 @@ void test_dealloc(int alloc_times = 10) { // 创建随机数生成器 std::random_device rd; std::mt19937 gen(rd()); // 以随机设备作为种子 - std::uniform_int_distribution<> distrib(1, 127 * 1024); // 设置随机数分布范围1-127 + std::uniform_int_distribution<> distrib(1, 127 * 100); // 设置随机数分布范围1-127 // 生成并输出随机数 std::map s; for (int i = 0; i < alloc_times; i++) { @@ -61,14 +61,19 @@ void test_dealloc(int alloc_times = 10) { } void test_multi_thread() { - std::thread t1(std::bind(test_dealloc, 200)); + std::thread t1(std::bind(test_dealloc, 1000)); // std::thread t2(std::bind(test_dealloc, 20)); t1.join(); // t2.join(); std::cout << "run successful" << std::endl; } +void big_alloc() { + void* ptr = tcmalloc(8 * 127 * 1024); + tcfree(ptr, 8 * 127 * 1024); +} + int main() { - test_multi_thread(); + big_alloc(); return 0; } \ No newline at end of file