How to get memory information on Linux system? - c++

How to get the total memory, used memory, free memory from C++ code on Linux system?

Run your program through valgrind. For a program called foo, for example:
valgrind foo
It'll run the program in a harness that keeps track of memory use and print out that information after the program terminates.
If you don't have valgrind installed for some reason, you should be able to find it in your distro's package repository.

As commented by Chris Stratton, you can -on Linux- query a lot of system information in /proc/ so read proc(5); which contain textual pseudo-files (a bit like pipes) to be read sequentially. These are not real disk files so are read very quickly. You'll need to open and close them at every measurement.
From inside a process, you can query its address space in virtual memory using /proc/self/maps -and /proc/self/smaps; outside of that process, for another process of pid 1234, use /proc/1234/maps & /proc/1234/smaps; you can get system wide memory information thru /proc/meminfo
So try the following commands in a terminal:
cat /proc/meminfo
cat /proc/$$/maps
cat /proc/$$/smaps
cat /proc/self/maps
to understand more what they could give you.
Be aware that malloc and free (used by new and delete) are often requesting space (from the kernel) using syscalls like mmap(2) but are managing previously free-d memory to reuse it, so often don't release memory back to the kernel with munmap. Read wikipage on C memory management. In other words, the used heap is not accessible outside the process (since some unused, but reusable for future malloc-s, memory remains mmap-ed). See also mallinfo(3) and malloc_stats(3).
As Justin Lardinois answered, use valgrind to detect memory leaks.
Advanced Linux Programming is a good book to read. It has several related chapters.

Related

Analyze Glibc heap memory

I research an embedded device that use GLIBC 2.25.
When I look at /proc/PID/maps I see under the heap section some anonymous sections ,I understand that sections create when the process use new
I dump those sections with dd and there is there interesting value that I want to understand is that buffer allocated or free, and what is the size of this buffer.
How can I do that please?
You can use the gdb (GNU Debugger) tool to inspect the memory of a running process. You can attach to the process using its PID and use the x command to examine memory at a specific address. You can also use the info proc mapping command to view the memory maps of the process, including the size of the heap. Additionally, you can use the heap command to list heap blocks and the malloc_info command to show detailed information about heap blocks.
You can also use the malloc_stats function to display information about the heap usage such as the number of bytes allocated, the number of bytes free and the number of bytes in use.
You can also use the pmap command to display the memory map of a process, including the heap size. This command is available on some systems and may not be present on others.
It's also worth noting that the /proc/PID/maps file can also give you an idea about the heap section of a process.
Please keep in mind that you need to have the right permission to access the process you want to inspect.
Instead of analyzing the memory from proc, you may want to try following options, limited to your env.
use tools like valgrind if you suspect any kind of leaks or invalid read/writes.
rather than looking at output of dd, attach to running process and inspect memory within process, gives you context to make sense of memory usage.
use logging to dump addresses of allocation/free/read/write. This allows you to build better understanding of memory usage.
You may have to use all of the above options depending upon the complexity of your task.

How does a debugger peek into another process' memory?

When every process has its own private memory space that no external process has access to, how does a debugger access a process' memory space?
For eg, I can attach gdb to a running process using gdb -p <pid>
The I can access all the memory of this process via gdb.
How is gdb able to do this?
I read the relevant questions in SO and no post seems to answer this point.
Since the question is tagged Linux and Unix, I'll expand a little on what David Scwartz says, which in short is "there is an API for that in the OS". The same basic principle applies in Windows as well, but the actual implementation is different, and although I suspect the implementation inside the OS does the same thing, there's no REAL way to know that, since we can't inspect the source code for Windows (one can, however, understanding how an OS and a processor works, sort of figure out what must be happening!)
Linux has a function called ptrace, that allows one process (following some checking of privileges) to inspect another process in various ways. It is one call, but the first parameter is a "what do you want to do". Here are some of the most basic examples - there are a couple of dozen others for less "common" operations:
PTRACE_ATTACH - connect to the process.
PTRACE_PEEKTEXT - look at the attached process' code memory (for example to disassemble the code)
PTRACE_PEEKDATA - look at the attached process' data memory (to display variables)
PTRACE_POKETEXT - write to process' code memory
PTRACE_POKEDATA - write to process' data memory.
PTRACE_GETREGS - copy the current register values.
PTRACE_SETREGS - change the current register values (e.g. a debug command of set variable x = 7, if x happens to be in a register)
In Linux, since memory is "all the same", PTRACE_PEEKTEXT and PTRACE_PEEKDATA are actually the same functionality, so you can give an address in code for PTRACE_PEEKDATA and an address, say, on the stack for PTRACE_PEEKTEXT and it will perfectly happily copy that back for you. The distinction is made for OS/processor combinations where memory is "split" between DATA memory and CODE memory. Most modern OS's and processors do not make that distinction. Same obviously applies to PTRACE_POKEDATA and PTRACE_POKETEXT.
So, say that the "debugger process" uses:
long data = ptrace(PTRACE_PEEKDATA, pid, 0x12340128, NULL);
When the OS is called with a PTRACE_PEEKDATA for address 0x12340128 it will "look" at the corresponding memory mapping for the memory at 0x12340128 (page-aligned that makes 0x12340000), if it exists, it will get mapped into the kernel, the data is then copied out from address 0x12340128 into the local memory, the memory unmapped, and the copied data passed back as the return value.
The manual states the initiating of the usage as:
The parent can initiate a trace by calling fork(2) and having the
resulting child do a PTRACE_TRACEME, followed (typically) by an exec(3).
Alternatively, the parent may commence trace of an existing process
using PTRACE_ATTACH.
For several pages more information do man ptrace.
When every process has its own private memory space that no external process has access to ...
That's false. External processes with the correct permissions and using the correct APIs can access other process' memory.
For linux debugging there is a system call ptrace which makes it possible to control another process on the system. Indeed, you need the rights to do that, which is typically given, if you are the owner of the process and you have not removed the permissions manually.
The os call ptrace itself enables access to memory, program counter, registers and nearly all other related things to read and write.
Please see man ptrace for details.
If you are interested how it works in a debugger, please have a look for the files in
gdb-x.x.x/gdb/linux-nat.c. There you can find the core stuff for accessing other processes to debug.

C++ Multithread program on linux memory issue

I'm developing a software that requires creation and deletion of a large number of threads.
When I create a thread the memory increases and when delete them (this is confirmed by using the command ps -mo THREAD -p <pid>), the memory related to the program/software does not decrease (top command). As a result I run out of memory.
I have used Valgrind to check for memory error/leak and I can't find any. This is on a debian box. Please let me know what the issue could be.
How are you deleting the threads?
The notes here http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html talk about needing to call join in some cases to free up resources.
You do not run out of memory.
The "free memory" you see in top command is actually not the memory that is available when required. Linux kernel uses as much as possible/useable of the free memory for its page cache. When a process requires memory, the kernel can throw away that page cache and provide that memory to a process.
In other words: linux uses the free memory, instead of just leaving it idling around...
Use free -m: In the row labeled "-/+ buffers/cache:" you will see the real amount of memory available for processes.

Understanding memory used by a program in bash (in ubuntu linux)

In some programming contests, problems have a memory limit (like 64MB or 256MB). How can I understand the memory used by my program (written in C++) with bash commands? Is there any way to limit the memory used by the program? The program should terminate if it uses more memory than the limit.
The command top will give you a list of all running processes and the current memory and swap or if you prefer the GUI you can use the System Monitor Application.
As for locking down memory usage you can always use the ulimit -v to set the maximum virtual address range for a process. This will cause malloc and its buddies to fail if they try to get more memory than that set limit.
Depending on how much work you want to put into it you can look at getrusage(), getrlimit(), and setrlimit(). For testing purposes you can call them at the beginning of your program or perhaps set them up in a parent process and fork your contest program off as a child. Then dispense with them when you submit your program for contest consideration.
Also, for process 1234, you could look into /proc/1234/maps or /proc/1234/smaps or run pmap 1234, all these commands display the memory map of that process of pid 1234.
Try to run cat /proc/self/maps to get an example (the memory map of the process running that cat command).
The memory map of a process is initialized by execve(2) and changed by the mmap(2) syscall (etc...)

Ubuntu System Monitor and valgrind to discover memory leaks in C++ applications

I'm writing an application in C++ which uses some external open source libraries. I tried to look at the Ubuntu System Monitor to have information about how my process uses resources, and I noticed that resident memory continues to increase to very large values (over 100MiB). This application should run in an embedded device, so I have to be careful.
I started to think there should be a (some) memory leak(s), so I'm using valgrind. Unfortunately it seems valgrind is not reporting significant memory leaks, only some minor issues in the libraries I'm using, nothing more.
So, do I have to conclude that my algorithm really uses that much memory? It seems very strange to me... Or maybe I'm misunderstanding the meaning of the columns of the System Monitor? Can someone clarify the meaning of "Virtual Memory", "Resident Memory", "Writable Memory" and "Memory" in the System Monitor when related to software profiling? Should I expect those values to immediately represent how much memory my process is taking in RAM?
In the past I've used tools that were able to tell me where I was using memory, like Apple Profiling Tools. Is there anything similar I can use in Linux as well?
Thanks!
Another tool you can try is the /lib/libmemusage.so library:
$ LD_PRELOAD=/lib/libmemusage.so vim
Memory usage summary: heap total: 4643025, heap peak: 997580, stack peak: 26160
total calls total memory failed calls
malloc| 42346 4528378 0
realloc| 52 7988 0 (nomove:26, dec:0, free:0)
calloc| 34 106659 0
free| 28622 3720100
Histogram for block sizes:
0-15 14226 33% ==================================================
16-31 8618 20% ==============================
32-47 1433 3% =====
48-63 4174 9% ==============
64-79 4736 11% ================
80-95 313 <1% =
...
(I quit vim immediately after startup.)
Maybe the histogram of block sizes will give you enough information to tell where leaks may be happening.
valgrind is very configurable; --leak-check=full --show-reachable=yes might be a good starting point, if you haven't tried it yet.
"Virtual Memory", "Resident Memory", "Writable Memory" and "Memory"
Virtual memory is the address space that your application has allocated. If you run malloc(1024*1024*100);, the malloc(3) library function will request 100 megabytes of storage from the operating system (or handle it out of the free lists). The 100 megabytes will be allocated with mmap(..., MAP_ANONYMOUS), which won't actually allocate any memory. (See the rant at the end of the malloc(3) page for details.) The OS will provide memory the first time each page is written.
Virtual memory accounts for all the libraries and executable objects that are mapped into your process, as well as your stack space.
Resident memory is the amount of memory that is actually in RAM. You might link against the entire 1.5 megabyte C library, but only use the 100k (wild guess) of the library required to support the Standard IO interface. The rest of the library will be demand paged in from disk when it is needed. Or, if your system is under memory pressure and some less-recently-used data is paged out to swap, it will no longer count against Resident memory.
Writable memory is the amount of address space that your process has allocated with write privileges. (Check the output of pmap(1) command: pmap $$ for the shell, for example, to see which pages are mapped to which files, anonymous space, the stack, and the privileges on those pages.) This is a reasonable indication of how much swap space the program might require in a worst-case swapping scenario, when everything must be paged to disk, or how much memory the process is using for itself.
Because there are probably 50--100 processes on your system at a time, and almost all of them are linked against the standard C library, all the processes get to share the read-only memory mappings for the library. (They also get to share all the copy-on-write private writable mappings for any files opened with mmap(..., MAP_PRIVATE|PROT_WRITE), until the process writes to the memory.) The top(1) tool will report the amount of memory that can be shared among processes in the SHR column. (Note that the memory might not be shared, but some of it (libc) definitely is shared.)
Memory is very vague. I don't know what it means.