Skip to content

Commit 251ea4c

Browse files
committed
Redesign code for unit_test_memory_leaks
1 parent 95eae42 commit 251ea4c

File tree

3 files changed

+195
-53
lines changed

3 files changed

+195
-53
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Author: David Robert Nadeau
3+
* Site: http://NadeauSoftware.com/
4+
* License: Creative Commons Attribution 3.0 Unported License
5+
* http://creativecommons.org/licenses/by/3.0/deed.en_US
6+
*/
7+
// https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-runtime-using-c
8+
9+
#if defined(_WIN32)
10+
#include <windows.h>
11+
#include <psapi.h>
12+
13+
#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
14+
#include <unistd.h>
15+
#include <sys/resource.h>
16+
17+
#if defined(__APPLE__) && defined(__MACH__)
18+
#include <mach/mach.h>
19+
20+
#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
21+
#include <fcntl.h>
22+
#include <procfs.h>
23+
24+
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
25+
#include <stdio.h>
26+
27+
#endif
28+
29+
#else
30+
#error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
31+
#endif
32+
33+
34+
35+
/**
36+
* Returns the peak (maximum so far) resident set size (physical
37+
* memory use) measured in bytes, or zero if the value cannot be
38+
* determined on this OS.
39+
*/
40+
size_t getPeakRSS( )
41+
{
42+
#if defined(_WIN32)
43+
/* Windows -------------------------------------------------- */
44+
PROCESS_MEMORY_COUNTERS info;
45+
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
46+
return (size_t)info.PeakWorkingSetSize;
47+
48+
#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
49+
/* AIX and Solaris ------------------------------------------ */
50+
struct psinfo psinfo;
51+
int fd = -1;
52+
if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
53+
return (size_t)0L; /* Can't open? */
54+
if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
55+
{
56+
close( fd );
57+
return (size_t)0L; /* Can't read? */
58+
}
59+
close( fd );
60+
return (size_t)(psinfo.pr_rssize * 1024L);
61+
62+
#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
63+
/* BSD, Linux, and OSX -------------------------------------- */
64+
struct rusage rusage;
65+
getrusage( RUSAGE_SELF, &rusage );
66+
#if defined(__APPLE__) && defined(__MACH__)
67+
return (size_t)rusage.ru_maxrss;
68+
#else
69+
return (size_t)(rusage.ru_maxrss * 1024L);
70+
#endif
71+
72+
#else
73+
/* Unknown OS ----------------------------------------------- */
74+
return (size_t)0L; /* Unsupported. */
75+
#endif
76+
}
77+
78+
79+
80+
81+
82+
/**
83+
* Returns the current resident set size (physical memory use) measured
84+
* in bytes, or zero if the value cannot be determined on this OS.
85+
*/
86+
size_t getCurrentRSS( )
87+
{
88+
#if defined(_WIN32)
89+
/* Windows -------------------------------------------------- */
90+
PROCESS_MEMORY_COUNTERS info;
91+
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
92+
return (size_t)info.WorkingSetSize;
93+
94+
#elif defined(__APPLE__) && defined(__MACH__)
95+
/* OSX ------------------------------------------------------ */
96+
struct mach_task_basic_info info;
97+
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
98+
if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
99+
(task_info_t)&info, &infoCount ) != KERN_SUCCESS )
100+
return (size_t)0L; /* Can't access? */
101+
return (size_t)info.resident_size;
102+
103+
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
104+
/* Linux ---------------------------------------------------- */
105+
long rss = 0L;
106+
FILE* fp = NULL;
107+
if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
108+
return (size_t)0L; /* Can't open? */
109+
if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
110+
{
111+
fclose( fp );
112+
return (size_t)0L; /* Can't read? */
113+
}
114+
fclose( fp );
115+
return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
116+
117+
#else
118+
/* AIX, BSD, Solaris, and Unknown OS ------------------------ */
119+
return (size_t)0L; /* Unsupported. */
120+
#endif
121+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <unistd.h>
2+
#include <ios>
3+
#include <iostream>
4+
#include <fstream>
5+
#include <string>
6+
// https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-runtime-using-c
7+
8+
//////////////////////////////////////////////////////////////////////////////
9+
//
10+
// process_mem_usage(double &, double &) - takes two doubles by reference,
11+
// attempts to read the system-dependent data for a process' virtual memory
12+
// size and resident set size, and return the results in KB.
13+
//
14+
// On failure, returns 0.0, 0.0
15+
16+
void process_mem_usage(double& vm_usage, double& resident_set)
17+
{
18+
using std::ios_base;
19+
using std::ifstream;
20+
using std::string;
21+
22+
vm_usage = 0.0;
23+
resident_set = 0.0;
24+
25+
// 'file' stat seems to give the most reliable results
26+
//
27+
ifstream stat_stream("/proc/self/stat",ios_base::in);
28+
29+
// dummy vars for leading entries in stat that we don't care about
30+
//
31+
string pid, comm, state, ppid, pgrp, session, tty_nr;
32+
string tpgid, flags, minflt, cminflt, majflt, cmajflt;
33+
string utime, stime, cutime, cstime, priority, nice;
34+
string O, itrealvalue, starttime;
35+
36+
// the two fields we want
37+
//
38+
unsigned long vsize;
39+
long rss;
40+
41+
stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
42+
>> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
43+
>> utime >> stime >> cutime >> cstime >> priority >> nice
44+
>> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
45+
46+
stat_stream.close();
47+
48+
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
49+
vm_usage = vsize / 1024.0;
50+
resident_set = rss * page_size_kb;
51+
}

unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp

Lines changed: 23 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,10 @@
11

22
#include <wsjcpp_core.h>
33
#include <wsjcpp_unit_tests.h>
4-
#include <unistd.h>
5-
#include <ios>
6-
#include <iostream>
7-
#include <fstream>
8-
#include <string>
94
#include <wsjcpp_yaml.h>
10-
#include <chrono>
11-
#include <thread>
12-
13-
//////////////////////////////////////////////////////////////////////////////
14-
//
15-
// process_mem_usage(double &, double &) - takes two doubles by reference,
16-
// attempts to read the system-dependent data for a process' virtual memory
17-
// size and resident set size, and return the results in KB.
18-
//
19-
// On failure, returns 0.0, 0.0
20-
21-
void process_mem_usage(double& vm_usage, double& resident_set)
22-
{
23-
using std::ios_base;
24-
using std::ifstream;
25-
using std::string;
26-
27-
vm_usage = 0.0;
28-
resident_set = 0.0;
29-
30-
// 'file' stat seems to give the most reliable results
31-
//
32-
ifstream stat_stream("/proc/self/stat",ios_base::in);
33-
34-
// dummy vars for leading entries in stat that we don't care about
35-
//
36-
string pid, comm, state, ppid, pgrp, session, tty_nr;
37-
string tpgid, flags, minflt, cminflt, majflt, cmajflt;
38-
string utime, stime, cutime, cstime, priority, nice;
39-
string O, itrealvalue, starttime;
40-
41-
// the two fields we want
42-
//
43-
unsigned long vsize;
44-
long rss;
45-
46-
stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
47-
>> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
48-
>> utime >> stime >> cutime >> cstime >> priority >> nice
49-
>> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
50-
51-
stat_stream.close();
52-
53-
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
54-
vm_usage = vsize / 1024.0;
55-
resident_set = rss * page_size_kb;
56-
}
5+
#include "get_current_rss.h"
6+
#include "process_mem_usage.h"
7+
578

589
// ---------------------------------------------------------------------
5910
// UnitTestMemoryLeaks
@@ -87,25 +38,44 @@ void UnitTestMemoryLeaks::executeTest() {
8738
std::string sFilepath = "./data-tests/for-memory-leak/some.yml";
8839
std::string sError;
8940

41+
// std::cout << "currentSize "<< getCurrentRSS() << std::endl;
42+
// std::cout << "peakSize "<< getPeakRSS() << std::endl;
43+
44+
// first use for memory alloc some
45+
for (int i = 0; i < 1000; i++) {
46+
WsjcppYaml yaml;
47+
if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) {
48+
WsjcppLog::err(TAG, sError);
49+
return;
50+
}
51+
}
52+
9053
process_mem_usage(nBeforeVm, nBeforeRss);
9154
// std::cout << "nBeforeVm: " << nBeforeVm << std::endl;
9255
// std::cout << "nBeforeRss: " << nBeforeRss << std::endl;
9356
compare("memory vm not null", (int)nBeforeVm > 0, true);
9457
compare("memory vm not null", (int)nBeforeRss > 0, true);
9558

59+
// std::cout << "currentSize "<< getCurrentRSS() << std::endl;
60+
// std::cout << "peakSize "<< getPeakRSS() << std::endl;
61+
62+
// code again check the memoty leak
63+
9664
for (int i = 0; i < 1000; i++) {
9765
WsjcppYaml yaml;
9866
if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) {
9967
WsjcppLog::err(TAG, sError);
10068
return;
10169
}
10270
}
103-
// std::this_thread::sleep_for(std::chrono::seconds(1));
71+
10472
process_mem_usage(nAfterVm, nAfterRss);
10573
// std::cout << "nAfterVm: " << nAfterVm << std::endl;
10674
// std::cout << "nAfterRss: " << nAfterRss << std::endl;
10775
compare("memory vm", (int)nAfterVm, (int)nBeforeVm);
10876
compare("memory rss", (int)nAfterRss, (int)nBeforeRss);
77+
// std::cout << "currentSize "<< getCurrentRSS() << std::endl;
78+
// std::cout << "peakSize "<< getPeakRSS() << std::endl;
10979
}
11080

11181
// ---------------------------------------------------------------------

0 commit comments

Comments
 (0)