Linux - KernelThis forum is for all discussion relating to the Linux kernel.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Not being versed in the linux kernel, I apologize ahead of time if this isn't a proper question in the kernel section.
Here's my problem:
I have algorithms coded in c++ that are very recursive in nature. This is something I'll probably not be able to change. So given this, I noticed something peculiar when I execute my code. Here's a sample program and analysis of what I'm experiencing...
./mem_test
::1
::2
... after the "::2", here's what top outputs...
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
11680 pseudosig 20 0 48200 33m 2432 S 0 1.2 0:00.04 mem_test
./mem_test
::1
::2
::3
::4
... after the "::4", here's what top outputs...
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
11680 pseudosig 20 0 79452 63m 2432 S 0 2.3 0:00.10 mem_test
Okay, so after the recursive function gets called the first time in main, it grows the stack (I'm assuming call stack) by 33m, and then after it fully returns and is sleeping after "::2", the stack doesn't resize back down. Then the same happens after the "::4" line, but by 2 fold.
My problem is that my recursive functions are consuming memory (from the call stack?) and after the recursion fully returns, the size of the call stack seems to stay the same, even though I'm sure the function has been popped off the call stack. How can I dynamically trim the stack after the recursive function calls have happened... or can I?
The stack isn't returned to the OS. But it will be reused by your program.
That is, the C++ runtime will allocate memory as necessary to grow the stack. When a function returns, it moves the stack pointer back down, but it doesn't return the frame to the OS. (If it did, functions calls would be unbearably slow. Besides, what's the kernel going to do with it? Give it to some other program, when it's almost certain you're going to grow into that space again?) When you put more stuff on the stack, it grows through the area that's already been allocated. When it hits the ceiling again, it will allocate more from the OS.
So this is what you'd expect to see. It's fine, unless you grew a ton of stack, then returned, and you know you won't be using it again, and you have a burning concern for the memory needs of other programs on the system.
(Caveat: This is my understanding, but I don't really know what I'm talking about.)
The stack isn't returned to the OS. But it will be reused by your program.
That is, the C++ runtime will allocate memory as necessary to grow the stack. When the function returns, it moves the stack pointer back down, but it doesn't return the frame to the OS. (If it did, functions calls would be unbearably slow.) When you put more stuff on the stack, it grows through the area that's already been allocated. When it hits the ceiling again, it will allocate more from the OS.
So this is what you'd expect to see. It's fine, unless you grew a ton of stack, then returned, and you know you won't be using it again, and you have a burning concern for the memory needs of other programs on the system.
(Caveat: This is my understanding, but I don't really know what I'm talking about.)
That makes sense. But is there a way to return frames that aren't in the scope of the current stack pointer in linux?
Okay... so I've spent a little more time with this problem. It turns out that my memory consumption problem has more than just recursive function calls as root of the problem. If you allocate a huge chunk of memory and delete/free it... then some of the memory space handed to the application from the kernel is given back to the kernel, but in general most of it is retained still by the application. This seems to be true for both the call stack and "heaped" memory.
I did seem to find a partial (if not total) solution. I've been digging around in <sys/mman.h>, which encompasses memory management declarations. There's a function madvise (int madvise(void *start, size_t length, int advice) ) that has a parameter option MADV_DONTNEED that "advises" the kernel that you probably won't need a certain memory block/range... so take it back. In the case of linux, the function call is less than a suggestion and more like a command. My problem now is how does one track their memory allocation so one could hand memory chunks back to the kernel? More specifically, how does one know what memory chunks for void *start and size_t length map to a recently allocated object?
Anyone had experience with this? Any suggestions are appreciated...
A solution to this already exists. There's a library called jemalloc that has a different memory allocator than just the standard C mallocl/etc (it's now in firefox 3.0) and it dynamically hands memory back and forth to the kernal, instead of just growing.
All you have to do is link against the library at compile time or runtime, and all is good. I've been using it for a while now... and it rocks.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.