f0430952 |
1 | // Created on: 2011-10-05 |
2 | // Created by: Kirill GAVRILOV |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
f0430952 |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
f0430952 |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
f0430952 |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
f0430952 |
15 | |
16 | #if (defined(_WIN32) || defined(__WIN32__)) |
17 | #include <windows.h> |
18 | #include <winbase.h> |
19 | #include <process.h> |
67a1064e |
20 | #include <malloc.h> |
5fecc495 |
21 | #include <psapi.h> |
f0430952 |
22 | #ifdef _MSC_VER |
23 | #pragma comment(lib, "Psapi.lib") |
24 | #endif |
25 | #elif (defined(__APPLE__)) |
26 | #include <mach/task.h> |
27 | #include <mach/mach.h> |
67a1064e |
28 | #include <malloc/malloc.h> |
8fa02385 |
29 | #else |
30 | #include <unistd.h> |
67a1064e |
31 | #include <malloc.h> |
f0430952 |
32 | #endif |
33 | |
34 | #include <string> |
35 | #include <sstream> |
36 | #include <fstream> |
37 | |
38 | #include <OSD_MemInfo.hxx> |
39 | |
40 | // ======================================================================= |
41 | // function : OSD_MemInfo |
42 | // purpose : |
43 | // ======================================================================= |
0be11733 |
44 | OSD_MemInfo::OSD_MemInfo (const Standard_Boolean theImmediateUpdate) |
f0430952 |
45 | { |
0be11733 |
46 | if (theImmediateUpdate) |
47 | { |
48 | Update(); |
49 | } |
50 | else |
51 | { |
52 | Clear(); |
53 | } |
f0430952 |
54 | } |
55 | |
0be11733 |
56 | |
f0430952 |
57 | // ======================================================================= |
0be11733 |
58 | // function : Clear |
f0430952 |
59 | // purpose : |
60 | // ======================================================================= |
0be11733 |
61 | void OSD_MemInfo::Clear() |
f0430952 |
62 | { |
f0430952 |
63 | for (Standard_Integer anIter = 0; anIter < MemCounter_NB; ++anIter) |
64 | { |
65 | myCounters[anIter] = Standard_Size(-1); |
66 | } |
0be11733 |
67 | } |
68 | |
69 | // ======================================================================= |
70 | // function : Update |
71 | // purpose : |
72 | // ======================================================================= |
73 | void OSD_MemInfo::Update() |
74 | { |
75 | Clear(); |
742cc8b0 |
76 | #ifndef OCCT_UWP |
7c65581d |
77 | #if defined(_WIN32) |
78 | #if (_WIN32_WINNT >= 0x0500) |
f0430952 |
79 | MEMORYSTATUSEX aStatEx; |
80 | aStatEx.dwLength = sizeof(aStatEx); |
81 | GlobalMemoryStatusEx (&aStatEx); |
82 | myCounters[MemVirtual] = Standard_Size(aStatEx.ullTotalVirtual - aStatEx.ullAvailVirtual); |
7c65581d |
83 | #else |
84 | MEMORYSTATUS aStat; |
85 | aStat.dwLength = sizeof(aStat); |
86 | GlobalMemoryStatus (&aStat); |
87 | myCounters[MemVirtual] = Standard_Size(aStat.dwTotalVirtual - aStat.dwAvailVirtual); |
88 | #endif |
f0430952 |
89 | |
90 | // use Psapi library |
91 | HANDLE aProcess = GetCurrentProcess(); |
9fa641d9 |
92 | #if (_WIN32_WINNT >= 0x0501) |
f0430952 |
93 | PROCESS_MEMORY_COUNTERS_EX aProcMemCnts; |
9fa641d9 |
94 | #else |
95 | PROCESS_MEMORY_COUNTERS aProcMemCnts; |
96 | #endif |
f0430952 |
97 | if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts))) |
98 | { |
9fa641d9 |
99 | #if (_WIN32_WINNT >= 0x0501) |
f0430952 |
100 | myCounters[MemPrivate] = aProcMemCnts.PrivateUsage; |
9fa641d9 |
101 | #endif |
f0430952 |
102 | myCounters[MemWorkingSet] = aProcMemCnts.WorkingSetSize; |
103 | myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize; |
104 | myCounters[MemSwapUsage] = aProcMemCnts.PagefileUsage; |
105 | myCounters[MemSwapUsagePeak] = aProcMemCnts.PeakPagefileUsage; |
106 | } |
8fa02385 |
107 | |
67a1064e |
108 | _HEAPINFO hinfo; |
109 | int heapstatus; |
110 | hinfo._pentry = NULL; |
111 | |
112 | myCounters[MemHeapUsage] = 0; |
113 | while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK) |
114 | { |
115 | if(hinfo._useflag == _USEDENTRY) |
116 | myCounters[MemHeapUsage] += hinfo._size; |
117 | } |
118 | |
f0430952 |
119 | #elif (defined(__linux__) || defined(__linux)) |
120 | // use procfs on Linux |
121 | char aBuff[4096]; |
122 | snprintf (aBuff, sizeof(aBuff), "/proc/%d/status", getpid()); |
123 | std::ifstream aFile; |
124 | aFile.open (aBuff); |
125 | if (!aFile.is_open()) |
126 | { |
127 | return; |
128 | } |
129 | |
130 | while (!aFile.eof()) |
131 | { |
132 | memset (aBuff, 0, sizeof(aBuff)); |
133 | aFile.getline (aBuff, 4096); |
134 | if (aBuff[0] == '\0') |
135 | { |
136 | continue; |
137 | } |
138 | |
139 | if (strncmp (aBuff, "VmSize:", strlen ("VmSize:")) == 0) |
140 | { |
141 | myCounters[MemVirtual] = atol (aBuff + strlen ("VmSize:")) * 1024; |
142 | } |
143 | //else if (strncmp (aBuff, "VmPeak:", strlen ("VmPeak:")) == 0) |
144 | // myVirtualPeak = atol (aBuff + strlen ("VmPeak:")) * 1024; |
145 | else if (strncmp (aBuff, "VmRSS:", strlen ("VmRSS:")) == 0) |
146 | { |
147 | myCounters[MemWorkingSet] = atol (aBuff + strlen ("VmRSS:")) * 1024; // RSS - resident set size |
148 | } |
149 | else if (strncmp (aBuff, "VmHWM:", strlen ("VmHWM:")) == 0) |
150 | { |
151 | myCounters[MemWorkingSetPeak] = atol (aBuff + strlen ("VmHWM:")) * 1024; // HWM - high water mark |
152 | } |
153 | else if (strncmp (aBuff, "VmData:", strlen ("VmData:")) == 0) |
154 | { |
155 | if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate]; |
156 | myCounters[MemPrivate] += atol (aBuff + strlen ("VmData:")) * 1024; |
157 | } |
158 | else if (strncmp (aBuff, "VmStk:", strlen ("VmStk:")) == 0) |
159 | { |
160 | if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate]; |
161 | myCounters[MemPrivate] += atol (aBuff + strlen ("VmStk:")) * 1024; |
162 | } |
163 | } |
164 | aFile.close(); |
67a1064e |
165 | |
166 | struct mallinfo aMI = mallinfo(); |
167 | myCounters[MemHeapUsage] = aMI.uordblks; |
168 | |
f0430952 |
169 | #elif (defined(__APPLE__)) |
170 | struct task_basic_info aTaskInfo; |
171 | mach_msg_type_number_t aTaskInfoCount = TASK_BASIC_INFO_COUNT; |
172 | if (task_info (mach_task_self(), TASK_BASIC_INFO, |
173 | (task_info_t )&aTaskInfo, &aTaskInfoCount) == KERN_SUCCESS) |
174 | { |
175 | // On Mac OS X, these values in bytes, not pages! |
176 | myCounters[MemVirtual] = aTaskInfo.virtual_size; |
177 | myCounters[MemWorkingSet] = aTaskInfo.resident_size; |
67a1064e |
178 | |
179 | //Getting malloc statistics |
180 | malloc_statistics_t aStats; |
181 | malloc_zone_statistics (NULL, &aStats); |
182 | |
183 | myCounters[MemHeapUsage] = aStats.size_in_use; |
f0430952 |
184 | } |
185 | #endif |
742cc8b0 |
186 | #endif |
f0430952 |
187 | } |
188 | |
189 | // ======================================================================= |
190 | // function : ToString |
191 | // purpose : |
192 | // ======================================================================= |
193 | TCollection_AsciiString OSD_MemInfo::ToString() const |
194 | { |
195 | TCollection_AsciiString anInfo; |
196 | if (myCounters[MemPrivate] != Standard_Size(-1)) |
197 | { |
198 | anInfo += TCollection_AsciiString(" Private memory: ") + Standard_Integer (ValueMiB (MemPrivate)) + " MiB\n"; |
199 | } |
200 | if (myCounters[MemWorkingSet] != Standard_Size(-1)) |
201 | { |
202 | anInfo += TCollection_AsciiString(" Working Set: ") + Standard_Integer (ValueMiB (MemWorkingSet)) + " MiB"; |
203 | if (myCounters[MemWorkingSetPeak] != Standard_Size(-1)) |
204 | { |
205 | anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemWorkingSetPeak)) + " MiB)"; |
206 | } |
207 | anInfo += "\n"; |
208 | } |
209 | if (myCounters[MemSwapUsage] != Standard_Size(-1)) |
210 | { |
211 | anInfo += TCollection_AsciiString(" Pagefile usage: ") + Standard_Integer (ValueMiB (MemSwapUsage)) + " MiB"; |
212 | if (myCounters[MemSwapUsagePeak] != Standard_Size(-1)) |
213 | { |
214 | anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemSwapUsagePeak)) + " MiB)"; |
215 | } |
216 | anInfo += "\n"; |
217 | } |
218 | if (myCounters[MemVirtual] != Standard_Size(-1)) |
219 | { |
220 | anInfo += TCollection_AsciiString(" Virtual memory: ") + Standard_Integer (ValueMiB (MemVirtual)) + " MiB\n"; |
221 | } |
67a1064e |
222 | if (myCounters[MemHeapUsage] != Standard_Size(-1)) |
223 | { |
224 | anInfo += TCollection_AsciiString(" Heap memory: ") + Standard_Integer (ValueMiB (MemHeapUsage)) + " MiB\n"; |
225 | } |
f0430952 |
226 | return anInfo; |
227 | } |
228 | |
229 | // ======================================================================= |
230 | // function : Value |
231 | // purpose : |
232 | // ======================================================================= |
233 | Standard_Size OSD_MemInfo::Value (const OSD_MemInfo::Counter theCounter) const |
234 | { |
235 | if (theCounter < 0 || theCounter >= MemCounter_NB) |
236 | { |
237 | return Standard_Size(-1); |
238 | } |
239 | return myCounters[theCounter]; |
240 | } |
241 | |
242 | // ======================================================================= |
243 | // function : ValueMiB |
244 | // purpose : |
245 | // ======================================================================= |
246 | Standard_Size OSD_MemInfo::ValueMiB (const OSD_MemInfo::Counter theCounter) const |
247 | { |
248 | if (theCounter < 0 || theCounter >= MemCounter_NB) |
249 | { |
250 | return Standard_Size(-1); |
251 | } |
252 | return (myCounters[theCounter] == Standard_Size(-1)) |
253 | ? Standard_Size(-1) : (myCounters[theCounter] / (1024 * 1024)); |
254 | } |
255 | |
0be11733 |
256 | // ======================================================================= |
257 | // function : ValuePreciseMiB |
258 | // purpose : |
259 | // ======================================================================= |
260 | Standard_Real OSD_MemInfo::ValuePreciseMiB (const OSD_MemInfo::Counter theCounter) const |
261 | { |
262 | if (theCounter < 0 || theCounter >= MemCounter_NB) |
263 | { |
264 | return -1.0; |
265 | } |
266 | return (myCounters[theCounter] == Standard_Size(-1)) |
267 | ? -1.0 : ((Standard_Real )myCounters[theCounter] / (1024.0 * 1024.0)); |
268 | } |
269 | |
f0430952 |
270 | // ======================================================================= |
271 | // function : ShowInfo |
272 | // purpose : |
273 | // ======================================================================= |
274 | TCollection_AsciiString OSD_MemInfo::PrintInfo() |
275 | { |
276 | OSD_MemInfo anInfo; |
277 | return anInfo.ToString(); |
278 | } |