linux-04-内存管理函数

2016-05-10  本文已影响138人  vera姐姐

今天:-malloc() free() sbrk() brk() mmap() munmap()

文件读写函数(UC版)

malloc() 和 free()

malloc()分配的是堆区的内存 一次申请小块内存时,系统会映射33个内存页,如果申请大块内存(31个内存页以上),系统会映射比申请稍多一点的内存页数。

malloc申请内存时,除了数据占用的空间外,还需要额外占用一些空间,用于存储附加数据。malloc申请内存时,会包括三部分:数据本身的空间,附加数据的空间,空的空间(预留空间)。附加数据存于 底层维护的双向链表中。预留空间的大小不确定,可大可小。

int* pi = malloc(4);

free(pi);//free()释放到哪里结束呢? 附加数据中有。

理论上因为malloc()会映射多个内存页,导致未分配的内存只要在33页之内都能使用;但是为了便于内存的管理(反复使用和控制),内存还是要 先分配再使用。

free()一定会释放被占用的虚拟内存地址,但是不一定会解除内存映射,对于malloc()来说,free()不会释放最后的33个内存页映射。最后33个内存页的映射在进程结束时才会释放。free()在大多数情况下会清空内存,但是不保证清()

free对于申请大块内存时会 全部解除映射。

经验:malloc()虽然地址不连续,但是不影响内存的使用;malloc()申请的内存在使用时不要过界,否则会影响下一次的内存分配和回收。

sbrk()和brk()

sbrk()和brk()是Unix的系统函数,机制和malloc是完全不同的。借助系统维护的一个位置进行内存的分配和回收。

void* sbrk(int increment) 功能就是分配//回收内存,大多数情况下用于分配内存。

参数increment是分配/回收的增量,为正数分配,为负数时,回收,为0时候取当前值。

返回值返回移动之前的位置,如果出错返回(void*) -1.

sbrk()在分配内存时非常方便,但回收内存时需要计算字节数,因此比较麻烦,不便于管理。brk()则相反。

一般情况下都是使用sbrk()分配内存,使用brk()释放内存(虽然这两个函数都可以分配和回收)。

sbrk()和brk()都是以一个内存页作为映射的基本单位的,一旦释放就会同时解除内存映射。

int brk(void* position) 功能就是分配/回收内存,一般用于回收内存

参数position就是新位置,无论原来的位置在哪里。返回:成功返回0,失败返回 -1。

brk() 和sbrk() 不会清除回收内存的数据,数据会在下次使用时被覆盖。

memset()可以设置内存的内容,一般用于清内存;

memcpy()可以复制内存的内容,一般用内存复制。

mmap() 和munmap()

用户层能使用的功能最强大的函数,可以设置一些内存相关的数据。mmap()实现内存映射,包括:映射物理内存和硬盘文件

各种权限和多个选项用位或 | 连接。

RWX

R-- 100

-W- 010

--X 001

读+写

100 | 010

void* mmap(void* addr,size_t length, int prot, int flats, int fd, off_t offset)

功能是内存映射,比sbrk()功能强大的多,失败返回-1

参数:addr指定映射的首地址,为0就是交给内核选择。

size 就是映射内存的大小

prot 就是内存的权限 一般是PROT——READ|PROT——WRITE

flats 就是映射的标识 主要包括:

MAP_SHARD MAP_PRIVATE 2选1,

MAP_SHARED 代表这块内存其他进程可以共享,但只对映射文件有效

MAP_PRIVATE就是其他进程不能共享,只能本进程使用。

MAP——ANONYMOUS代表映射 物理内存,不写就映射硬盘文件(默认映射)。

fd 是文件描述符,映射文件时有效,映射物理内存为0.

offset 是文件偏移量,选择映射文件的位置,映射物理内存 为0;

返回:成功返回映射的首地址,失败返回MAP——FAILED

用户空间的程序不能进入内核空间,但很多功能需要内核实现,因此内核空间 提供了一系列的函数, 允许用户空间调用,从而进入内核空间。这一系列的函数通称为 系统调用(system call)。比如:标C的malloc() 不能进入Unix内核,但内存分配必须依赖内核,内核提供了系统调用sbrk()和mmap(),帮助malloc()进入内核完成内存的分配。

系统调用的使用方式和标C函数没有任何区别,因此无需过多关注。

eg:

int* pi =mmap(NULL,//首地址内核选择

6              4,//分配4字节,映射还是按一页算

7              PROT_READ | PROT_WRITE,//权限

8              MAP_PRIVATE | MAP_ANONYMOUS,//映射物理内存用    PRIVATE,ANNONYMOU    S代表映射物理内存

9              0,0);//文件描述符映射物理内存给()

10  if(pi == MAP_FAILED)

11  {

12    perror("MMAP");

13    return -1;

14  }

15  *pi = 100;

16 printf("%d\n",*pi);

17 munmap(pi,4);

上一篇下一篇

猜你喜欢

热点阅读