鉴于此C程序打印私有虚拟内存:
#include <stdio.h>
#include <stdlib.h>
#define _PSTAT64
#include <sys/param.h>
#include <sys/pstat.h>
#include <sys/unistd.h>
void pstatvm()
{
struct pst_vm_status pst;
int idx, count;
long long shared_vm = 0;
long long shared_ram = 0;
long long private_vm = 0;
long long private_ram = 0;
pid_t pid = getpid();
idx=0;
count = pstat_getprocvm(&pst, sizeof(pst), (size_t)pid, idx);
while (count > 0) {
switch ((long)pst.pst_type) {
case PS_IO: break;
/* Don't count IO space. It really is not RAM or swap. */
default:
if (pst.pst_flags & PS_SHARED) {
shared_vm += (long long) pst.pst_length;
shared_ram += (long long)pst.pst_phys_pages;
} else {
private_vm += (long long) pst.pst_length;
private_ram += (long long)pst.pst_phys_pages;
}
break;
}
idx++;
count = pstat_getprocvm(&pst, sizeof(pst), (size_t)pid, idx);
}
printf("%d\t\t", pid);
printf("%lldK\t\t", shared_vm*4);
printf("%lldK\t\t", shared_ram*4);
printf("%lldK\t\t", private_vm*4);
printf("%lldK\n", private_ram*4);
}
int main()
{
void *p=NULL;
int cont = 1;
printf("pid\t\tshared_vm\tshared_ram\tprivate_vm\tprivate_ram\n");
while(cont < 100)
{
p = malloc((cont*10)*1024*1024);
if (p == NULL)
{
printf("exit\n");
exit(1);
}
pstatvm();
free(p); p=NULL;
sleep(1);
cont += 10;
}
printf ("\n\n");
cont = 0;
while(cont < 10)
{
sleep(100);
pstatvm();
++cont;
}
}
为什么private_vm没有被OS发布?
pid shared_vm shared_ram private_vm private_ram
8988 3436K 2432K 26880K 320K
8988 3436K 2432K 129280K 336K
8988 3436K 2432K 231680K 352K
8988 3436K 2432K 334080K 368K
8988 3436K 2432K 436480K 384K
8988 3436K 2432K 538880K 400K
8988 3436K 2432K 641280K 416K
8988 3436K 2432K 743680K 432K
8988 3436K 2432K 846080K 448K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
8988 3436K 2432K 948480K 464K
在Linux / Unix中,所有应用程序内存都是虚拟的,除非将其换成光盘,否则它指向物理内存中的某个位置。每个页面都可以单独寻址,因此当您的应用程序堆(使用malloc()分配的内存)对您的应用程序显示为连续时,它实际上可能遍布您的物理RAM
答案 0 :(得分:4)
如果要分配大的内存区域,以便在应用程序不再需要它们时真正释放它们,那么直接使用POSIX mmap
和munmap
函数,而不是依赖于行为足够大的malloc
个请求被转换为mmap
。
这可能是GNU C库在GNU / Linux上的工作方式,但它不是标准定义的要求,因此期望不可移植。
显然,HP-UX系统的malloc
保留了即使是大型分配的底层存储。 但是,请注意VM大小的增量大约为100 Mb 。这表明分配器正在重用先前释放的内存,从而避免了碎片。也就是说,当你释放300 Mb块然后分配400 Mb时,它不会保留原来的300 Mb,然后分配一个全新的400 Mb块;它意识到之前释放的300 Mb空间可以扩展。在分配器中可能存在其他隐藏策略,您的程序的分配模式没有演示。 我们从您的程序中得知的是,当我们进行单个大型分配然后释放它时,分配器能够保留它并扩展它以满足更大的分配请求。这不是证明分配器始终保持释放的大量分配;它可能只是针对这种情况的优化(也许是为了支持重复的realloc
)。
答案 1 :(得分:3)
malloc()
和free()
没有义务分配/解除分配虚拟内存。他们应付堆。而且,如果需要malloc()
使用sbrk()
来扩大堆,free()
不会缩回堆,因此分配的虚拟内存量与{{1}之后的相同}。