glibc内存分配释放示例

23 篇文章 0 订阅

glibc中的内存管理采用的是ptmalloc机制其malloc和free函数操作的是进程虚拟地址空间。

malloc分配内存是通过brk(sbrk)mmap这两个系统调用实现的,brk(sbrk)通过移动进程地址空间的heap顶部指针向地址增大/缩小方向移动,mmap是在进程地址空间的heap和stack中间分配虚拟地址空间。

不管使用的是哪种内存分配方式,仅仅都是操作虚拟地址空间,并没有实际物理内存的分配,只有当进程需要访问该虚拟地址空间时,发生缺页中断才会实际分配物理内存并建立映射关系。

对于内存释放free而言,由brk(sbrk)分配的内存并不一定会真正释放,默认情况下,只有当heap最高地址空间的空闲内存超过128K(可由M_TRIM_THRESHOLD选项调节)时,才会执行内存紧缩操作(trim)释放内存。即使没有真正释放,当应用程序再次请求内存并且之前free的内存大小满足请求条件时可以直接返回给应用程序再次使用。

mmap分配的内存在free时会真正释放。

具体实现可以参看https://blog.csdn.net/just_lion/article/details/80592027

以下是示例程序:

一,sbrk内存分配模式,(单次分配<128k)

1)分配2048个64k大小的内存

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define chunk_size 64*1024
#define chunk_num 2048

void* chunk_array[chunk_num];

int main(void)
{
    int i,j;

    for (i=0; i<chunk_num; i++)
    {
        chunk_array[i] = malloc(chunk_size);
        for(j =0; j<chunk_size; j++)
        {
            *((char*)chunk_array[i] + j) = '\0';
        }
    }

    sleep(20000);

    return 0;
}

此时通过top -p <pid>查看内存占用为:

其中VIRT为虚拟内存占用, RES为物理内存占用。

2) 从heap底部(低地址)执行部分free

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define chunk_size 64*1024
#define chunk_num 2048

void* chunk_array[chunk_num];

int main(void)
{
    int i,j;

    for (i=0; i<chunk_num; i++)
    {
        chunk_array[i] = malloc(chunk_size);
        for(j =0; j<chunk_size; j++)
        {
            *((char*)chunk_array[i] + j) = '\0';
        }
    }

    for (i=0; i<chunk_num-10; i++)
    {
        free(chunk_array[i]);
    }

    sleep(20000);

    return 0;
}

 此时查看内存占用,没有任何内存释放,因为heap顶部没有释放。

3) 从heap顶部(高地址)执行部分free

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define chunk_size 64*1024
#define chunk_num 2048

void* chunk_array[chunk_num];

int main(void)
{
    int i,j;

    for (i=0; i<chunk_num; i++)
    {
        chunk_array[i] = malloc(chunk_size);
        for(j =0; j<chunk_size; j++)
        {
            *((char*)chunk_array[i] + j) = '\0';
        }
    }

    for (i=chunk_num-1; i>10; i--)
    {
        free(chunk_array[i]);
    }

    sleep(20000);

    return 0;
}

查看内存占用:

此时内存基本释放完毕。

 

二,mmap内存分配模式,(单次分配>=128k)

1) 分配2048个128k大小的内存

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define chunk_size 128*1024
#define chunk_num 2048

void* chunk_array[chunk_num];

int main(void)
{
    int i,j;

    for (i=0; i<chunk_num; i++)
    {
        chunk_array[i] = malloc(chunk_size);
        for(j =0; j<chunk_size; j++)
        {
            *((char*)chunk_array[i] + j) = '\0';
        }
    }

    sleep(20000);

    return 0;
}

此时内存占用为:

2) 从低地址执行部分free

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define chunk_size 128*1024
#define chunk_num 2048

void* chunk_array[chunk_num];

int main(void)
{
    int i,j;

    for (i=0; i<chunk_num; i++)
    {
        chunk_array[i] = malloc(chunk_size);
        for(j =0; j<chunk_size; j++)
        {
            *((char*)chunk_array[i] + j) = '\0';
        }
    }

    for (i=0; i<chunk_num-10; i++)
    {
        free(chunk_array[i]);
    }

    sleep(20000);

    return 0;
}

此时查看内存占用:

可见内存基本释放完毕。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值