mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-04 17:27:00 +00:00
encapsulate and instrument
This commit is contained in:
42
include/xrpl/basics/MallocTrim.h
Normal file
42
include/xrpl/basics/MallocTrim.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef XRPL_BASICS_MALLOCTRIM_H_INCLUDED
|
||||
#define XRPL_BASICS_MALLOCTRIM_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
struct MallocTrimReport
|
||||
{
|
||||
bool supported{false};
|
||||
int trimResult{-1};
|
||||
long rssBeforeKB{-1};
|
||||
long rssAfterKB{-1};
|
||||
|
||||
long
|
||||
deltaKB() const
|
||||
{
|
||||
return rssAfterKB - rssBeforeKB;
|
||||
}
|
||||
};
|
||||
|
||||
/** Attempt to return freed memory to the operating system.
|
||||
*
|
||||
* This function is only effective on Linux with glibc. On other platforms,
|
||||
* it returns a report indicating the operation is unsupported.
|
||||
*
|
||||
* @param tag Optional identifier for logging/debugging purposes
|
||||
* @param journal Journal for logging diagnostic information
|
||||
* @return Report containing before/after memory metrics
|
||||
*
|
||||
* @note This is intended for use after cache sweeps or other operations
|
||||
* that free significant amounts of memory.
|
||||
*/
|
||||
MallocTrimReport
|
||||
mallocTrim(std::optional<std::string> const& tag, beast::Journal journal);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
@@ -2,12 +2,9 @@
|
||||
#define XRPL_BASICS_TAGGEDCACHE_IPP_INCLUDED
|
||||
|
||||
#include <xrpl/basics/IntrusivePointer.ipp>
|
||||
#include <xrpl/basics/MallocTrim.h>
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
namespace ripple {
|
||||
|
||||
template <
|
||||
@@ -331,9 +328,7 @@ TaggedCache<
|
||||
.count()
|
||||
<< "ms";
|
||||
|
||||
#ifdef __GLIBC__
|
||||
(void)malloc_trim(0);
|
||||
#endif
|
||||
mallocTrim(std::optional<std::string>(m_name), m_journal);
|
||||
}
|
||||
|
||||
template <
|
||||
|
||||
95
src/libxrpl/basics/MallocTrim.cpp
Normal file
95
src/libxrpl/basics/MallocTrim.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/MallocTrim.h>
|
||||
|
||||
#include <boost/predef.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
|
||||
std::string
|
||||
readFile(std::string const& path)
|
||||
{
|
||||
std::ifstream ifs(path);
|
||||
if (!ifs.is_open())
|
||||
return {};
|
||||
return std::string(
|
||||
std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
long
|
||||
parseVmRSSkB(std::string const& status)
|
||||
{
|
||||
// "VmRSS: 123456 kB"
|
||||
auto pos = status.find("VmRSS:");
|
||||
if (pos == std::string::npos)
|
||||
return -1;
|
||||
|
||||
pos += 6; // past "VmRSS:"
|
||||
while (pos < status.size() && status[pos] == ' ')
|
||||
++pos;
|
||||
|
||||
long value = -1;
|
||||
std::sscanf(status.c_str() + pos, "%ld", &value);
|
||||
return value; // in kB
|
||||
}
|
||||
|
||||
#endif // __GLIBC__ && BOOST_OS_LINUX
|
||||
|
||||
} // namespace detail
|
||||
|
||||
MallocTrimReport
|
||||
mallocTrim(
|
||||
[[maybe_unused]] std::optional<std::string> const& tag,
|
||||
beast::Journal journal)
|
||||
{
|
||||
MallocTrimReport report;
|
||||
|
||||
#if !(defined(__GLIBC__) && BOOST_OS_LINUX)
|
||||
JLOG(journal.debug()) << "malloc_trim not supported on this platform";
|
||||
return report;
|
||||
#else
|
||||
|
||||
report.supported = true;
|
||||
|
||||
if (journal.debug())
|
||||
{
|
||||
std::string const tagStr = tag.value_or("default");
|
||||
pid_t const pid = ::getpid();
|
||||
std::string const statusPath =
|
||||
"/proc/" + std::to_string(pid) + "/status";
|
||||
|
||||
auto const statusBefore = detail::readFile(statusPath);
|
||||
report.rssBeforeKB = detail::parseVmRSSkB(statusBefore);
|
||||
|
||||
report.trimResult = ::malloc_trim(0);
|
||||
|
||||
auto const statusAfter = detail::readFile(statusPath);
|
||||
report.rssAfterKB = detail::parseVmRSSkB(statusAfter);
|
||||
|
||||
JLOG(journal.debug())
|
||||
<< "malloc_trim tag=" << tagStr << " result=" << report.trimResult
|
||||
<< " rss_before=" << report.rssBeforeKB << "kB"
|
||||
<< " rss_after=" << report.rssAfterKB << "kB"
|
||||
<< " delta=" << report.deltaKB() << "kB";
|
||||
}
|
||||
else
|
||||
{
|
||||
report.trimResult = ::malloc_trim(0);
|
||||
}
|
||||
|
||||
return report;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
Reference in New Issue
Block a user