考虑以下这个 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?
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中
while
)中系统调用的日志,就像在Linux中通过strace或在FreeBSD中通过truss(在HP-UX中是tusc http://knowledgebase.progress.com/articles/Article/3669)打印的那样?这个大小的malloc可能会使用brk/sbrk来进行真正的堆分配,也可能会使用mmap;相比于碎片化的堆,mmap更容易取消映射(你的libc实现是什么?)。你能否将`pstatvm();`从内部while循环移动到循环后的位置(printf/pstat可能有它们自己的malloc调用,这会阻止堆空间的重用/碎片化)?HP-UX和libc的版本是多少? - osgx