在UNIX/LINUX中,程序运行时动态内存以堆的方式来分配。程序而言,它使用的动态内存地址是虚拟内存, 代码用内存和数据用内存,一个从上往下,一个从下往上增长。 CODE:
malloc(32 * 1024) --->;sbrk += 32 * 1024
free() --->;sbrk 不减少。 但如如果再来一次 malloc(32 * 1024) ---->;sbrk 也不增,使用原有空间. 但对于LINUX来说它是要以内存的最大数收缩的; 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 不减少。只是多了个空洞. } CODE:
/* linux kernel code */
brk() /* * sys_brk() for the most part doesn't need the global kernel * lock, except 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; /******虚拟内存在这里收缩******/ /* 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; /****这就是返回值*****/ up_write(&mm->;mmap_sem); return retval; } 在LINUX中sbrk(0)能返回比较精确的虚拟内存使用情况, sbrk把程序的数据段增加increment个字节。sbrk不是一个系统调用,而是一个C的库函数。用increment为0来调用sbrk函数,可以返回程序当前所停留的数据段位置。
|
|