简体   繁体   English

为什么没有释放分配了malloc的虚拟内存?

[英]Why is virtual memory allocated with malloc not released?

Given this C program where the private virtual memory is printed: 鉴于此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;
    }

}

Why is the private_vm not released by the OS? 为什么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

From http://www.linuxforums.org/forum/programming-scripting/153369-solved-where-does-memory-allocated-malloc-actually-come.html : 来自http://www.linuxforums.org/forum/programming-scripting/153369-solved-where-does-memory-allocated-malloc-actually-come.html

In Linux/Unix, all application memory is virtual, and unless it is swapped out to disc it points to a location in physical memory. 在Linux / Unix中,所有应用程序内存都是虚拟的,除非将其换出到光盘,否则它指向物理内存中的某个位置。 Each page can be separately addressed, so while your application heap (memory allocated with malloc()) appears to your application as contiguous, it may actually be spread out all over your physical RAM 每个页面都可以单独寻址,因此当您的应用程序堆(使用malloc()分配的内存)对您的应用程序显示为连续时,它实际上可能遍布您的物理RAM

If you want to allocate large regions of memory such that they are really freed when your application no longer needs them, then use the POSIX mmap and munmap functions directly, rather than relying on the behavior that sufficiently large malloc requests are translated to mmap . 如果要分配大的内存区域,以便在应用程序不再需要它们时真正释放它们,那么直接使用POSIX mmapmunmap函数,而不是依赖于足够大的malloc请求转换为mmap

That may be how the GNU C Library works on GNU/Linux, but it isn't a standard-defined requirement, and so the expectation isn't portable. 这可能是GNU C库在GNU / Linux上的工作方式,但它不是标准定义的要求,因此期望不可移植。

Evidently, your HP-UX system's malloc is retaining the underlying storage of even large allocations. 显然,HP-UX系统的malloc保留了即使是大型分配的底层存储。 However, note how the increments in VM size are just around 100 Mb . 但是,请注意VM大小的增量大约为100 Mb This shows that the allocator is re-using the previously freed memory, avoiding fragmentation. 这表明分配器正在重用先前释放的内存,从而避免了碎片。 That is to say, when you free a 300 Mb block and then allocate a 400 Mb, it's not retaining the original 300 Mb and then allocating a brand new 400 Mb block; 也就是说,当你释放300 Mb块然后分配400 Mb时,它不会保留原来的300 Mb,然后分配一个全新的400 Mb块; it realizes that the 300 Mb space that was previously freed can just be extended. 它意识到之前释放的300 Mb空间可以扩展。 There could be additional hidden strategies in the allocator which your program's allocation pattern doesn't demonstrate. 在分配器中可能存在其他隐藏策略,您的程序的分配模式没有演示。 All we know from your program is that when we make a single large allocation and then free it, the allocator is able to keep it around and extend it to meet an even larger allocation request. 我们从您的程序中得知的是,当我们进行单个大型分配然后释放它时,分配器能够保留它并扩展它以满足更大的分配请求。 That doesn't prove that the allocator always keeps around large allocations that were freed; 这并不能证明分配器始终保持被释放的大量分配; it could be an optimization just for this case (perhaps for the sake of supporting a repeated realloc ). 它可能只是针对这种情况的优化(也许是为了支持重复的realloc )。

malloc() and free() are not obligated to allocate / deallocate virtual memory. malloc()free()没有义务分配/释放虚拟内存。 They cope with heap. 他们应付堆。 And regardless to fact that malloc() uses sbrk() to enlarge heap if need, free() doesn't shrink heap back, so amount of allocated virtual memory remains the same as immediately after malloc() . 而且无论事实如果malloc()在需要时使用sbrk()来扩大堆, free()不会收缩堆,因此分配的虚拟内存量与malloc()之后的内容保持一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM