diff --git a/server/System.cpp b/server/System.cpp index bc93ed3c..c06d34e1 100644 --- a/server/System.cpp +++ b/server/System.cpp @@ -22,10 +22,11 @@ #include #include +#include "Common/JemallocUtil.h" +#include "Common/macros.h" +#include "System.h" #include "Util/logger.h" #include "Util/uv_errno.h" -#include "System.h" -#include "Common/macros.h" using namespace std; using namespace toolkit; @@ -55,6 +56,16 @@ string System::execute(const string &cmd) { static constexpr int MAX_STACK_FRAMES = 128; +static void save_jemalloc_stats() { + string jemalloc_status = JemallocUtil::get_malloc_stats(); + if (jemalloc_status.empty()) { + return; + } + ofstream out(StrPrinter << exeDir() << "/jemalloc.json", ios::out | ios::binary | ios::trunc); + out << jemalloc_status; + out.flush(); +} + static void sig_crash(int sig) { signal(sig, SIG_DFL); void *array[MAX_STACK_FRAMES]; @@ -149,6 +160,12 @@ void System::startDaemon(bool &kill_parent_if_failed) { } void System::systemSetup(){ + +#ifdef ENABLE_JEMALLOC_DUMP + //Save memory report when program exits + atexit(save_jemalloc_stats); +#endif //ENABLE_JEMALLOC_DUMP + #if !defined(_WIN32) struct rlimit rlim,rlim_new; if (getrlimit(RLIMIT_CORE, &rlim)==0) { diff --git a/src/Common/JemallocUtil.cpp b/src/Common/JemallocUtil.cpp new file mode 100644 index 00000000..fa2de64a --- /dev/null +++ b/src/Common/JemallocUtil.cpp @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. +* +* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). +* +* Use of this source code is governed by MIT license that can be found in the +* LICENSE file in the root of the source tree. All contributing project authors +* may be found in the AUTHORS file in the root of the source tree. +*/ + + +#include "JemallocUtil.h" +#include "Util/logger.h" +#ifdef USE_JEMALLOC +#include +#include +#endif + +namespace mediakit { + +void set_profile_active(bool active) { +#ifdef USE_JEMALLOC + int err = mallctl("prof.active", nullptr, nullptr, (void *)&active, sizeof(active)); + if (err != 0) { + WarnL << "mallctl failed with: " << err; + } +#endif +} + +void JemallocUtil::enable_profiling() { + set_profile_active(true); +} +void JemallocUtil::disable_profiling() { + set_profile_active(false); +} +void JemallocUtil::dump(const std::string &file_name) { +#ifdef USE_JEMALLOC + auto *c_str = file_name.c_str(); + int err = mallctl("prof.dump", nullptr, nullptr, &c_str, sizeof(const char *)); + if (err != 0) { + std::cerr << "mallctl failed with: " << err << std::endl; + } +#endif +} +std::string JemallocUtil::get_malloc_stats() { +#ifdef USE_JEMALLOC + std::string res; + malloc_stats_print([](void *opaque, const char *s) { ((std::string *)opaque)->append(s); }, &res, "J"); + return res; +#else + return ""; +#endif +} + +void JemallocUtil::some_malloc_stats(const std::function &fn) { +#ifdef USE_JEMALLOC + constexpr std::array STATS = { + "stats.allocated", "stats.active", "stats.metadata", "stats.metadata_thp", + "stats.resident", "stats.mapped", "stats.retained", "stats.zero_reallocs", + }; + + for (const char *stat : STATS) { + size_t value; + size_t len = sizeof(value); + auto err = mallctl(stat, &value, &len, nullptr, 0); + if (err != 0) { + ErrorL << "Failed reading " << stat << ": " << err; + continue; + } + fn(stat, value); + } +#endif +} +} // namespace mediakit \ No newline at end of file diff --git a/src/Common/JemallocUtil.h b/src/Common/JemallocUtil.h new file mode 100644 index 00000000..796a58bb --- /dev/null +++ b/src/Common/JemallocUtil.h @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. +* +* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). +* +* Use of this source code is governed by MIT license that can be found in the +* LICENSE file in the root of the source tree. All contributing project authors +* may be found in the AUTHORS file in the root of the source tree. +*/ + +#ifndef ZLMEDIAKIT_JEMALLOCUTIL_H +#define ZLMEDIAKIT_JEMALLOCUTIL_H +#include +#include +namespace mediakit { +class JemallocUtil { +public: + JemallocUtil() = default; + ~JemallocUtil() = default; + + static void enable_profiling(); + + static void disable_profiling(); + + static void dump(const std::string &file_name); + static std::string get_malloc_stats(); + static void some_malloc_stats(const std::function &fn); +}; +} // namespace mediakit +#endif // ZLMEDIAKIT_JEMALLOCUTIL_H