Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CCCS-13: Add Memory Measuring #14

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@
"stdexcept": "cpp",
"streambuf": "cpp",
"typeinfo": "cpp",
"ctime": "cpp"
"ctime": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"condition_variable": "cpp",
"csignal": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_set": "cpp",
"ratio": "cpp",
"fstream": "cpp",
"mutex": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stop_token": "cpp",
"thread": "cpp"
}
}
5 changes: 5 additions & 0 deletions Src/Emitter/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <iostream>
#include <unistd.h>

#include "../Library/MemoryMonitor/MemoryMonitor.hpp"
#include "../Library/ELog/easylogging++.h"

#include "../Library/BinaryWrapper.hpp"
Expand Down Expand Up @@ -36,6 +37,10 @@ int main()
LOG(DEBUG) << "Emitter started";
LOG(INFO) << "Emitter started";

MemoryStatus ms = MemoryMonitor::ForCurrentProcess();

LOG(INFO) << ms.To2String();

sleep(5);

Client client = *(new Client(8080));
Expand Down
2 changes: 2 additions & 0 deletions Src/Emitter/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
BINDIR := ./Bin
BINARY := $(addprefix $(BINDIR)/, emitter)

LIB_MEMORY := ../Library/MemoryMonitor/MemoryMonitor.cpp ../Library/MemoryMonitor/MemoryStatus.cpp
LIB_SIGNALS := ../Library/Measure.cpp ../Library/CommTerm.cpp ../Library/BinaryWrapper.cpp
LIB_NETWORK := ../Library/Client.cpp
LIB_LOGGING := ../Library/ELog/easylogging++.cc

SOURCE := ./Main.cpp \
$(LIB_MEMORY) \
$(LIB_LOGGING) \
$(LIB_NETWORK) \
$(LIB_SIGNALS) \
Expand Down
14 changes: 14 additions & 0 deletions Src/Library/MemoryMonitor/MemoryMonitor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "MemoryMonitor.hpp"

MemoryMonitor::MemoryMonitor()
{
}

MemoryMonitor::~MemoryMonitor()
{
}

MemoryStatus MemoryMonitor::ForCurrentProcess()
{
return MemoryStatus("/proc/self/status");
}
19 changes: 19 additions & 0 deletions Src/Library/MemoryMonitor/MemoryMonitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef Included_MemoryMonitor
#define Included_MemoryMonitor


#include "MemoryStatus.hpp"

class MemoryMonitor
{
private:

public:

MemoryMonitor();
~MemoryMonitor();

static MemoryStatus ForCurrentProcess();
};

#endif
74 changes: 74 additions & 0 deletions Src/Library/MemoryMonitor/MemoryStatus.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <fstream> // std::ifstream

#include "MemoryStatus.hpp"

std::string MemoryStatus::To2String()
{
tm *t = std::localtime(&time);
char *str = (char *)calloc(80, 1);
snprintf(str, 80, "%d:%d:%d VmSize=%u VmData=%u VmStk=%u VmSwap=%u \n",
t->tm_hour, t->tm_min, t->tm_sec,
VmSize, VmData, VmStk, VmSwap);

return std::string(str);
}

MemoryStatus::MemoryStatus(std::string path)
{
time = std::time(nullptr);

std::ifstream infile (path, std::ifstream::in);
std::string line;

while (std::getline(infile, line))
{
if (line.find("VmPeak") == 0)
VmPeak = parseLine(line);

if (line.find("VmSize:") == 0)
VmSize = parseLine(line);

if (line.find("VmLck:") == 0)
VmLck = parseLine(line);

if (line.find("VmHWM:") == 0)
VmHWM = parseLine(line);

if (line.find("VmRSS:") == 0)
VmRSS = parseLine(line);

if (line.find("VmData:") == 0)
VmData = parseLine(line);

if (line.find("VmStk:") == 0)
VmStk = parseLine(line);

if (line.find("VmExe:") == 0)
VmExe = parseLine(line);

if (line.find("VmLib:") == 0)
VmLib = parseLine(line);

if (line.find("VmPTE:") == 0)
VmPTE = parseLine(line);

if (line.find("VmSwap:") == 0)
VmSwap = parseLine(line);
}

infile.close();
}

int MemoryStatus::parseLine(std::string lineIn)
{
int i = lineIn.find_first_of(" \t");
int j = lineIn.find_last_of(" \t");
int l = j - i;
std::string substr = lineIn.substr(i, l);
int v = atoi(substr.c_str());
return v;
}

MemoryStatus::~MemoryStatus()
{
}
90 changes: 90 additions & 0 deletions Src/Library/MemoryMonitor/MemoryStatus.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#ifndef Included_MemoryStatus
#define Included_MemoryStatus

#include <string> // std::string
#include <ctime> // std::time_t

/// @brief The memory representation structure. \
The descriptions of the parameters was taken from \
Bela Lugosi's Dead, Jim (ewx.livejournal.com/579283.html)
class MemoryStatus
{
private:
int parseLine(std::string lineIn);

public:
std::time_t time;

/// @brief Peak virtual memory size - \
Peak total address space used. In other words, \
the sum of all virtual memory areas in the process, \
whatever they are used for.
u_int32_t VmPeak = 0;

/// @brief total program size \
Current total address space used. In other words, \
the sum of all virtual memory areas in the process, \
whatever they are used for.
u_int32_t VmSize = 0;

/// @brief Locked memory size \
Pages locked into RAM with mlock(). \
They cannot be swapped, but may be moved \
to a different location in (physical) RAM.
u_int32_t VmLck = 0;

/// @brief Peak resident set size ("high water mark"). \
Process’s peak usage of physical RAM.
u_int32_t VmHWM = 0;

/// @brief Size of memory portions. \
Process’s current usage of physical RAM.
u_int32_t VmRSS = 0;

/// @brief Size of data, stack, and text segments. \
Calculated as the total address space usage (i.e. VmSize) \
with shared and stack pages subtracted. This seems rather arbitrary \
(especially considering the caveat about VmSize below).
u_int32_t VmData = 0;

/// @brief Size of data, stack, and text segments. \
Size of the stack of the initial thread in the process. \
This is true even in /proc/${pid}/task/${thread}/status - \
the stacks for other threads are not distinguished from any other kind of page.
u_int32_t VmStk = 0;

/// @brief Size of text segment. \
Equivalent to the difference between endcode and startcode fields \
from /proc/${pid}/stat. The documentation describes these as bounding \
the address range in which program text can run; but this seems to be incorrect, \
based on both inspection and a little test program. Rather they seem to be the bounds \
of the text section of the initial executable, making VmExe the size of that text section. \
It does not include shared libraries, JIT compiler output, etc.
u_int32_t VmExe = 0;

/// @brief Size of shared library code. \
Counts executable pages with a VmExe subtracted. \
The intent must be to measure the quantity of shared library/plugin code \
in the process, but presumably it’ll include code generated by JIT compilers too.
u_int32_t VmLib = 0;

/// @brief Size of page table entries. \
eems to be the amount of kernel memory occupied by page table entries, \
though being 100% certain about that requires more familiarity with the mm directory than I can claim.
u_int32_t VmPTE = 0;

/// @brief Size of swap usage (the number of referred swapents). \
The total swap space used. That will MAP_ANONYMOUS pages that have been swapped out, \
and dirtied pages from memory-mapped files (for instance executables and shared libraries) \
but won’t include the text (code) sections of executables. \
It’s another relatively recent addition, appearing in kernel 2.6.34.
u_int32_t VmSwap = 0;


std::string To2String();

MemoryStatus(std::string path);
~MemoryStatus();
};

#endif