简体   繁体   中英

How to detect programmatically count of bytes allocated by process on Heap?

How to detect programmatically count of bytes allocated by process on Heap? This test should work from process itself.

I think mallinfo() is what you want:

#include <malloc.h>


struct mallinfo *info;

info = mallinfo();

printf ("total allocated space:  %llu bytes\n", info->uordblks);
printf ("total free space:       %llu bytes\n", info->fordblks);

The struct mallinfo structure is technical, and specific to the malloc() implementation. But the information you want is in there. Here is how I report the values:

mallinfo.arena = "Total Size (bytes)" 
mallinfo.uordblks = "Busy size (bytes)" 
mallinfo.fordblks = "Free size (bytes)" 
mallinfo.ordblks = "Free blocks (count)" 
mallinfo.keepcost = "Top block size (bytes)" 
mallinfo.hblks = "Blocks mapped via mmap() (count)" 
mallinfo.hblkhd = "Bytes mapped via mmap() (bytes)"

These two are allegedly not used, but they seem to change on my system, and thus might be valid:

mallinfo.smblks = "Fast bin blocks (count)"
mallinfo.fsmblks = "Fast bin bytes (bytes)"

And the other interesting value is returned by "sbrk (0)"

There are a number of possibilities.

How accurate do you need it to be? You can get some useful data via cat /proc/${PID}/status | grep VmData .

You can #define your own malloc() , realloc() , calloc() , and free() functions, wrapping the real functions behind your own counter. You can do really cool things here with __FILE__, __LINE__, & __func__ to facilitate identifying core leaks in simple tests. But it will only instrument your own code!

(Similarly, you can also redefine the default operator new and operator delete methods, both array and non-array variants, and both throwing std::bad_alloc and std::nothrow_t variants. Again, this will only instrument your own code!)

(Be aware: On most C++ systems, new ultimately invokes malloc() . It doesn't have to. Especially with in-place new ! But typically new does make use of malloc() . (Or it operates on a region of memory that has previously been malloc()'ed .) Otherwise you'd get into really funky stuff with multiple heap managers...)

You can use sbrk(0) to see where the data segment is currently set. That's not so great. It's a very coarse measurement, and it doesn't account for holes (unused memory regions) in the heap. (You're much better off with the VmData line from /proc/${PID}/status .) But if you're just looking for a general idea...

You can trap malloc()/free()/etc by writing your own shared library and forcing your process to use it instead of the real versions via LD_PRELOAD . You can use dlopen()/dlsym() to load & invoke the *real* malloc()/free()/etc . This works quite beautifully. The original code is unmodified, not even recompiled. But be aware of re-entrant situations when coding this library, and that your process will initially invoke malloc()/calloc()/realloc() before dlopen()/dlsym() can complete loading the real functions.

You might check out tools like Valgrind , though that's really aimed more at memory leaks.


Then again, perhaps mtrace() is what you want? Or __malloc_hook ? Very proprietary (GNU) & nonstandard... But you are tagged "Linux"...

There's no easy, automatic way to do it, if that's what you're asking. You basically have to manually keep track of heap allocations yourself using a counter variable. The problem is that it's difficult to control which parts of your program are allocating memory on the heap, especially if you're using a lot of libraries out of your control. To complicate things further, there's two ways a program might allocate heap memory: new or malloc . (Not to mention direct OS calls like sbrk .)

You can override global operator new , and have each call to new increase a global tally. However, this won't necessarily include times when your program calls malloc , or when your program uses some class-specific new override. You can also override malloc using a macro, but this is not necessarily portable. And you'd also have to override all the variations of malloc , like realloc , calloc , etc. All of this is further complicated by the fact that on some implementations, new itself may call malloc .

So, essentially, it's very difficult to do this properly from within your program. I'd recommend using a memory profiler tool instead.

A speculative solution: redefine new and delete operators.

On each new operator call, a number of bytes to allocate is passed. Allocate a bit more memory and store the amount of bytes allocated within. Add this amount to global variable that holds the heap size.

On delete operator call, check the value you stored before you dispose the memory. Subtract it from that global variable.

If you're on windows, you can use GetProcessHeap() , HeapQueryInfo() to retrieve information about the processes heap. An example of walking the heap from MSDN

Since you've tagged your question 'linux' it might help to look at some of the information provided in the /proc directory. I haven't researched this a lot so I can only give you a starting point.

/proc/<your programs pid> contains files with some information about your process from the viewpoint of the kernel. There is a symlink /proc/self that will always about the process your investigating this from.

The files you might be most interested in are stat , statm and status . The latter is more human-readable, whereas the former two give the same info in a more machine-readable format.

A starting point about how to interpret the content of those files is available in the proc(5) manpage.

其他然后跟踪您的所有内存分配我不相信有一种方法可以计算堆大小或使用情况

Use malloc_info() . Have fun with the XML aspect of it. mallinfo() (as shown in another answer) does a similar thing but is restricted to 32-bit values... a foolish thing to rely on in 2010+.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM