Warrior wrote:
malloc() and free() are not functions used by applications rather than for use with system functions that require memory where that amount is unknown. Correct? Ok.
Nope, not correct. They
are the functions used by applications, and you pass the
exact amount of memory required to malloc().
Application has the heap which is a lump of virutal memory they use to do thier own thing. When thier lump of virtual memory becomes to small for thier needs they ask for more then I grant them more.
Not quite, but almost. See below.
Paging manages the free pages and used pages and pages not in use into free pages. IIRC All malloc does is select the first page which is big enough for thier request?
No.
You have the kernel, which handles the physical and virtual memory (which includes paging). It also manages the setting up of new processes, and offers the system services.
An executable image consists of:
- .text section which holds the executable code,
- .data section which holds data for which size and value was known at compile time, and
- a number defining .bss size for data for which only size but not value was known at compile time.
When a process is set up, the address space is filled with the executable image, with the .bss size reserved and initialized to zero. In addition, the stack is set up. In addition, somewhere in the address space there's the C runtime provided by the system. malloc() and free() are part of that C runtime. Both function modify the heap, which is empty at start.
The C runtime holds an internal pool of memory. Let's just assume the traditional approach, where that memory starts at the end of .bss, with the stack growing downward from the top of the address space. Not all of the 4G address space are actually mapped to physical or virtual memory, however. (Or each process would enlargen the swap space requirement by a full 4G.) The C runtime just "knows" where the "available" addresses end.
This is, you might note, still completely ignorant of paging et al. - for the runtime, memory is contiguous. (And it must be, because applications customarily require contiguous memory in excess of a single page size.)
If your application now comes to the point of requiring memory that wasn't known at compile-time - like, allocating a buffer large enough to hold a certain bitmap file - it calls malloc(). If the chunk requested can be satisfied from the internal pool held by the C runtime, the runtime marks that part of its internal pool as reserved and returns a pointer to it. The kernel is blissfully unaware of this.
If the request
cannot be satisfied by the internal pool held by the runtime, the runtime calls the kernel to enlarge that internal pool, i.e. increase the amount of memory actually mapped anywhere, physical or virtual. (The function is called sbrk() in POSIX, morecore() or something like that in other OS'.) The kernel does whatever is necessary - paging out dormant memory areas to free up physical memory, for example - and attaches additional pages to the process' address space. The kernel returns the new limit to the available heap to the C library, which in turn returns a pointer to a large-enough chunk of memory to the application.
On the reverse, when the application returns memory chunks to the C runtime with free(), at some point the C runtime holds lots of unused memory which
should be returned to the kernel, so the kernel could pass physical memory to
other processes and shrink the used swap space.
Doing all this in a fast
and efficient manner, that's the art of memory management.
I hope I clarified the how-to a bit.