@@ -16,7 +16,12 @@ limitations under the License.
1616
1717#include < stddef.h>
1818
19+ #include < cstdint>
20+ #include < fstream>
21+ #include < iostream>
1922#include < ostream>
23+ #include < sstream>
24+ #include < string>
2025
2126#ifdef __linux__
2227#include < malloc.h>
@@ -37,6 +42,38 @@ namespace memory {
3742
3843const size_t MemoryUsage::kValueNotSet = 0 ;
3944
45+ namespace {
46+
47+ #if defined(__linux__)
48+ // Returns the current VM swap in kilobytes on Linux.
49+ int64_t GetCurrentVmSwapKb () {
50+ std::ifstream status_file (" /proc/self/status" );
51+ if (!status_file.is_open ()) {
52+ return -1 ;
53+ }
54+ std::string line;
55+ while (std::getline (status_file, line)) {
56+ if (line.rfind (" VmSwap:" , 0 ) == 0 ) {
57+ std::stringstream ss (line);
58+ std::string key;
59+ int64_t value_kb;
60+ // The line format is "VmSwap: 1234 kB"
61+ // We can extract the key ("VmSwap:") and the numeric value ("1234").
62+ ss >> key >> value_kb;
63+ if (!ss.fail ()) {
64+ return value_kb;
65+ } else {
66+ return -1 ; // Indicate parsing error
67+ }
68+ }
69+ }
70+ // If the VmSwap line is not found, it means 0 swap is being used.
71+ return 0 ;
72+ }
73+ #endif
74+
75+ } // namespace
76+
4077bool MemoryUsage::IsSupported () {
4178#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
4279 return true ;
@@ -50,6 +87,10 @@ MemoryUsage GetMemoryUsage() {
5087 rusage res;
5188 if (getrusage (RUSAGE_SELF, &res) == 0 ) {
5289 result.mem_footprint_kb = res.ru_maxrss ;
90+ int64_t vm_swap_kb = GetCurrentVmSwapKb ();
91+ if (vm_swap_kb >= 0 ) {
92+ result.private_footprint_bytes = (vm_swap_kb + res.ru_maxrss ) * 1024 ;
93+ }
5394 }
5495#if defined(__NO_MALLINFO__)
5596 result.total_allocated_bytes = -1 ;
@@ -71,19 +112,24 @@ MemoryUsage GetMemoryUsage() {
71112 if (status == KERN_SUCCESS) {
72113 result.mem_footprint_kb =
73114 static_cast <int64_t >(vm_info.phys_footprint / 1024.0 );
115+ // TODO: b/421171145 - Consider subtracting shared_resident_kb.
116+ result.private_footprint_bytes = vm_info.phys_footprint ;
74117 }
75118 struct mstats stats = mstats ();
76119 result.total_allocated_bytes = stats.bytes_total ;
77120 result.in_use_allocated_bytes = stats.bytes_used ;
78121#elif defined(_WIN32)
79- PROCESS_MEMORY_COUNTERS process_memory_counters;
122+ PROCESS_MEMORY_COUNTERS_EX process_memory_counters;
80123 HANDLE process_handle = GetCurrentProcess ();
81124 if (process_handle != nullptr &&
82- GetProcessMemoryInfo (process_handle, &process_memory_counters,
125+ GetProcessMemoryInfo (process_handle,
126+ (PROCESS_MEMORY_COUNTERS*)&process_memory_counters,
83127 sizeof (process_memory_counters))) {
84128 result.mem_footprint_kb = process_memory_counters.WorkingSetSize / 1024 ;
129+ result.private_footprint_bytes = process_memory_counters.PrivateUsage ;
85130 } else {
86131 result.mem_footprint_kb = -1 ;
132+ result.private_footprint_bytes = -1 ;
87133 }
88134 CloseHandle (process_handle);
89135 HANDLE process_heap = GetProcessHeap ();
@@ -108,7 +154,9 @@ void MemoryUsage::AllStatsToStream(std::ostream* stream) const {
108154 << mem_footprint_kb / 1000.0 << " MB, total non-mmapped heap size = "
109155 << total_allocated_bytes / 1000.0 / 1000.0
110156 << " MB, in-use heap size = "
111- << in_use_allocated_bytes / 1000.0 / 1000.0 << " MB" ;
157+ << in_use_allocated_bytes / 1000.0 / 1000.0
158+ << " MB, private footprint = "
159+ << private_footprint_bytes / 1000.0 / 1000.0 << " MB" ;
112160}
113161
114162} // namespace memory
0 commit comments