The main task of BRK and sbrk is to map virtual memory to memory. In gnuc, the memory allocation is as follows:
The virtual memory space accessible to each process is 3 GB. However, during program compilation, it is impossible or unnecessary to allocate such a large space for the program. Only a small data segment space is allocated, the dynamically allocated space in the program is allocated from this block. If this space is insufficient, the malloc function family (such as realloc and calloc) will call the sbrk function to move the lower bound of the data segment. The sbrk function maps the virtual address space to the memory under the management of the kernel, used by the malloc function. (See Linux kernel scenario analysis)
# Include <unistd. h>
Int BRK (void * end_data_segment );
Void * sbrk (ptrdiff_t increment );
Description
BRK sets the end Of the data segment to the value specified by end_data_segment, when that value is reasonable, the system does have enough memory and the process does not exceed its max data size (see setrlimit (2 )).
Sbrk increments the program's data space by increment bytes. sbrk isn't a system call, it is just a C library wrapper. calling sbrk with an increment of 0 can be used to find the current location of the program
Break.
Return Value
On success, BRK returns zero, and sbrk returns a pointer to the start of the new area. On error,-1 is returned, and errno is set to enomem.
Sbrk is a C library function instead of a system call. System calling usually provides a minimum function, while library functions usually provide more complex functions.
In Linux, when a program is loaded into memory, the kernel creates code segments, data segments, and stack segments for the user's process address space. The idle areas between data segments and stack segments are used for dynamic memory allocation.
The member variables start_code and end_code in the kernel data structure mm_struct are the start and end addresses of the Process Code segment, start_data and end_data are the start and end addresses of the process data segment, and start_stack is the start address of the process stack segment, start_brk is the starting address for dynamic memory allocation of processes (the starting address of the heap), and a BRK (the last address of the heap) is the ending address for dynamic memory allocation.
The basic function of dynamic memory allocation in C language is malloc (), and the basic implementation in Linux is called through the BRK System of the kernel. BRK () is a very simple system call, but simply changes the BRK value of the member variable of the mm_struct structure.
MMAP system calls enable more useful dynamic memory allocation, which can map all or part of a disk file to the user space, the read/write operation of a process changes to the read/write memory operation. The do_mmap_pgoff () function in the Linux/MM/MMAP. c file is the core of MMAP system calling implementation. Do_mmap_pgoff () Code only creates a vm_area_struct structure and assigns the file structure parameter to its member variable m_file, without actually loading the file content into the memory.
One of the basic concepts of Linux memory management is that physical ing of an address is established only when an address is actually accessed.
========================================================== ========================================================== =
C language and Memory Allocation Method
(1) distribution from the static storage area. The program has been allocated when it is compiled, and the program exists throughout the entire runtime. For example, global variables and static variables.
(2) create a stack. When a function is executed, the storage units of local variables in the function can be created on the stack. When the function is executed, these storage units are automatically released. Stack memory allocation
It is highly efficient to calculate the instruction set built into the processor, but the allocated memory capacity is limited.
(3) allocate from the stack, also known as dynamic memory allocation. When the program runs, it uses malloc or new to apply for any amount of memory. The programmer is responsible for releasing the memory with free or delete. The lifetime of the dynamic memory is determined by us. It is very flexible to use, but it has the most problems.
Functions related to memory application in C language include alloc, calloc, malloc, free, realloc, and sbrk. here, alloc applies for memory from the stack, so it does not need to be released. the memory allocated by malloc is located in the heap and does not initialize the memory content. Therefore, basically, after malloc, call the memset function to initialize the memory space. calloc will initialize this part of memory, set to 0. while realloc adjusts the memory size applied for by malloc. the Applied memory needs to be released using the function free. sbrk increases the data segment size;
Malloc, calloc, and free are basically implemented by the C function library and have nothing to do with OS. the C function library uses a certain structure to store the current amount of available memory. if the malloc size of the program exceeds the reserved space in the library, the BRK system call will be called to increase the available space and then the space will be allocated. when free, the released memory is not immediately returned to the OS, but stored in the internal structure. for example, BRK is similar to a wholesale database, where a large memory size can be applied to the operating system at one time, while functions such as malloc are similar to retail, meeting the runtime requirements. this mechanism is similar to buffering.
The reason for using this mechanism: system calls cannot support memory allocation of any size (some system calls only support applying for memory of a fixed size and its multiples. In this case, the allocation of small memory will result in a waste; the system call request memory is expensive, involving the conversion of user and core states.
Both the functions malloc () and calloc () can be used to allocate dynamic memory space, but the two are slightly different.
The malloc () function has a parameter, that is, the size of the memory space to be allocated:
Void * malloc (size_t size );
The calloc () function has two parameters: the number of elements and the size of each element. The product of these two parameters is the size of the memory space to be allocated:
Void * calloc (size_t numelements, size_t sizeofelement );
If the call is successful, both the malloc () and calloc () functions return the first address of the allocated memory space.
The main difference between the malloc () and calloc () functions is that the former Cannot initialize the allocated memory space, while the latter can. If the memory space allocated by the malloc () function has never been used before, each of them may be 0; otherwise, if the memory space has been allocated, released, and re-allocated, a variety of data may be left over. That is to say, when the program using the malloc () function starts (the memory space has not been re-allocated), it can run normally, but after a period of time (the memory space has been re-allocated) problems may occur.
The calloc () function initializes every bit in the allocated memory space to zero. That is to say, if you allocate memory for elements of the character or Integer type, these elements are always initialized to zero. If you allocate memory to elements of the pointer type, these elements are usually (but cannot be guaranteed) initialized to a null pointer; if you allocate memory for elements of the real number type, these elements (only in some computers) may be initialized to zero of the floating point type.
Another difference between the malloc () and calloc () functions is that the calloc () function returns an array composed of some objects, but the malloc () function returns only one object. To explicitly allocate memory space for an array, some programmers use the calloc () function. However, apart from whether to initialize the allocated memory space, most Programmers think that there is no difference between the following two function call methods:
Calloc (numelements, sizeofelement );
Malloc (numelements * sizeofelement );
It should be explained that, theoretically (according to the ansic standard) arithmetic operations of pointers can only be performed in a specified array, but in practice, even if the C compiler or translator follows this rule, many C Programs still break through this restriction. Therefore, although the malloc () function cannot return an array, the memory space it allocates can still be used for an array (the same for the realloc () function, even though it cannot return an array ).
In short, when you select between the calloc () function and the malloc () function, you only need to consider whether to initialize the allocated memory space, instead of considering whether the function can return an array.
When the program runs malloc but is not free, memory leakage may occur. some of the memory is not used, but it is not free. Therefore, the system considers that this part of memory is still in use, resulting in a constant request for memory from the system. however, memory leakage only means that when the program is running and the program exits, the OS will reclaim all resources. therefore, restarting the program properly may be helpful.
Sbrk (INT incr) This function is used to increase the amount of space allocated to the Data Segment of the calling program. The original form of the BRK function is: int BRK (void * endds)
Its function is to change the data segment space allocation.
Char * P;
P = malloc (1 );
The memory size pointed to by P is 1 byte.
BRK (p + 100)
The memory size pointed to by P is 101 bytes.
The Virtual Memory allocated by a program is not a byte, but a byte to give you a page, because the physical memory can only be mapped to pages. When you want another byte, the remaining space on this page is provided to you.
Note that most of the UNIX virtual memory usage only increases and decreases.
Code: malloc (32*1024) --->; sbrk + = 32*1024
Free () --->; sbrk is not reduced.
However, if you try again
Malloc (32*1024) ---->; sbrk does not increase, use the original space.
But for Linux, it is to shrink with the maximum number of memory;
Code: <code>
A = malloc (32*1024) -->; sbrk + = 32*1024
B = malloc (32*1024) -->; sbrk + = 32*1024
If (****){
Free (B); --->; sbrk-= 32*1024;
}
Else {
Free (a); --->; sbrk is not reduced. There is just an empty hole.
}
</Code>
Code: <code>
/* Linux kernel code */
BRK ()
/*
* Sys_brk () for the most part doesn't need the global Kernel
* Lock, wait t when an application is doing something nasty
* Like trying to un-BRK an area that has already been mapped
* To a regular file. In this case, the unmapping will need
* To invoke file system routines that need the global lock.
*/
Asmlinkage unsigned long sys_brk (unsigned long BRK)
{
Unsigned long rlim, retval;
Unsigned long newbrk, oldbrk;
Struct mm_struct * Mm = Current->; mm;
Down_write (& mm->; mmap_sem );
If (BRK <mm->; end_code)
Goto out;
Newbrk = page_align (BRK );
Oldbrk = page_align (Mm->; BRK );
If (oldbrk = newbrk)
Goto set_brk;
/****** The virtual inside exists here to shrink ******/
/* Always allow shrinking BRK .*/
If (BRK <= mm->; BRK ){
If (! Do_munmap (mm, newbrk, oldbrk-newbrk ))
Goto set_brk;
Goto out;
}
/* Check against rlimit ..*/
Rlim = Current->; rlim [rlimit_data]. rlim_cur;
If (rlim <rlim_infinity & BRK-mm->; start_data>; rlim)
Goto out;
/* Check against existing MMAP mappings .*/
If (find_vma_intersection (mm, oldbrk, newbrk + page_size ))
Goto out;
/* Check if we have enough memory ..*/
If (! Vm_enough_memory (newbrk-oldbrk) >;>; page_shift ))
Goto out;
/* OK, looks good-let it rip .*/
If (do_brk (oldbrk, newbrk-oldbrk )! = Oldbrk)
Goto out;
Set_brk:
Mm->; BRK = BRK;
Out:
Retval = mm->; BRK;/***** this is the returned value *****/
Up_write (& mm->; mmap_sem );
Return retval;
}
</Code>
In Linux, sbrk (0) can return more precise virtual memory usage,
In Solaris/HP, sbrk (0) returns the page-based virtual memory usage. Use sbrk (0) to return the current memory used by the program.
<Code>
Main (){
Int start, end;
Start = sbrk (0 );
....
Malloc (***);
....
End = sbrk (0 );
Printf ("Hello I used % d vmemory", end-Start );
}
</Code>