1.man malloc
2 .预备知识
在实现malloc之前,需要先解释一些Linux系统内存相关的知识。
2.1 Linux内存管理
2.1.1 虚拟内存地址与物理内存地址
为了简单,现代操作系统在处理内存地址时,普遍采用虚拟内存地址技术。即在汇编程序(或机器语言)层面,当涉及内存地址时,都是使用虚拟内存地址。采用这种技术时,每个进程仿佛自己独享一片2N字节的内存,其中N是机器位数。例如在64位CPU和64位操作系统下,每个进程的虚拟地址空间为264Byte。
这种虚拟地址空间的作用主要是简化程序的编写及方便操作系统对进程间内存的隔离管理,真实中的进程不太可能(也用不到)如此大的内存空间,实际能用到的内存取决于物理内存大小。
由于在机器语言层面都是采用虚拟地址,当实际的机器码程序涉及到内存操作时,需要根据当前进程运行的实际上下文将虚拟地址转换为物理内存地址,才能实现对真实内存数据的操作。这个转换一般由一个叫MMU(Memory Management Unit)的硬件完成。
malloc分配4g以下空间
malloc分配4g以下空间
说起malloc,但凡对C/C++有点基础的人在编写代码的时候都用过。我们调用malloc接口分配一段连续的内存空间,不使用时使用free可以释放这段内存空间。这些我们都已经比较的熟悉了。但是你知道malloc背后的调用机制吗?
C语言程序员都知道,malloc只是C语言库标准提供的一个普通函数,我们实现的malloc和库函数比起来效率要低很多,但是可以通过编写一个简单的malloc来体现C库的精髓,我们实现的malloc和库的实现原理上市一致的。
一,malloc的定义:
根据标准C的定义,malloc的函数原型是这样的:
void* malloc(size_t size);
函数要求如下:
malloc函数分配的内存大小至少为size参数所指定的字节数。
malloc的返回值是一个void类型的指针,我们必须强制转化为我们需要的类型的指针。
多次调用malloc所分配的地址不能有重叠部分,除非某次molloc所分配的地址被free释放掉了。
malloc应该尽快的完成内存额分配并且返回。
实现malloc的同时实现calloc和realloc和free。
如果是子啊Linux环境下,可以使用
man malloc
查看malloc的具体定义。
二,Linux的内存管理
1.虚拟内存地址与物理内存地址棚携的关系:
现代操作系统在处理内存地址时普遍的采用虚拟内存地址技术,什么事虚拟内存技术呢?
这种技术使每个进程“仿佛独享”一块2N字节的内存(N是机器的位数),例如在64位的操作系统下,每个进程的虚拟内存空间是264B。这种虚拟内存空间的作用是简化程序的编写并且方便操作系统对进程之间的隔离管理。
虚拟内存技术是由MMU和页表构成的,MMU是一种映射算法,它从虚拟内存地址映射到物理内存地址上,单位是页
2.什么是页表?
在现代操作系统中,不管是虚拟内存地址还是链行伏物理内存地址,都是以页尾单位管理的,而不是大家以为的字节。(一个内存页是一段固定的地址,典型的内存页的大小是4K)。所以内存地址可以分为页号和页内偏移量
三,Linux进程级的内存管理
首先,我们可以了解一下一个进程的内核空间:
可以看到一个进程地址空间的主要成分为:
正文:这是整个用户空间的更低地址部分,存放的是指令(也就是程序所编译成的可执行机器码)
初始化数据段:这里存放的是初始化过的全局变量
未初始化数据段:这里存放的是未初始化的全局变量
Heap:堆,这是我们本文重点关注的地方,堆自低地址向高地址增长,后面要讲到的brk相关的系统调用就是从这里分配内存
Stack:这是栈区域,自高地址向低地址增长
命令行参数和环境变量:用户调用的更底层。
我们都知道,在malloc分配空间时是在Heap上分配的,实质上, Linux维护一个break指针,这个指针指向堆空间的某个地址。从带迟堆起始地址到break之间的地址空间为映射好的,可以供进程访问;而从break往上,是未映射的地址空间,如果访问这段空间则程序会报错。
由上文知道,要增加一个进程实际的可用堆大小,就需要将break指针向高地址移动。Linux通过brk和rk系统调用操作break指针。两个系统调用的原型如下:
int brk(void *addr);
void *rk(intptr_t increment);
brk将break指针直接设置为某个地址,而rk将break从当前位置移动increment所指定的增量。brk在执行成功时返回0,否则返回-1并设置errno为ENOMEM;rk成功时返回break移动之前所指向的地址,否则返回(void *)-1。
一个小技巧是,如果将increment设置为0,则可以获得当前break的地址。
另外需要注意的是,由于Linux是按页进行内存映射的,所以如果break被设置为没有按页大小对齐,则系统实际上会在最后映射一个完整的页,从而实际已映射的内存空间比break指向的地方要大一些。但是使用break之后的地址是很危险的(尽管也许break之后确实有一小块可用内存地址)。
linux malloc应用例子的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux malloc应用例子,Linux下的Malloc:实用案例分享,如何实现一个malloc,malloc分配4g以下空间的信息别忘了在本站进行查找喔。
香港服务器首选筋斗云,2H2G首月10元开通。
筋斗云()提供简单好用,价格厚道的香港/美国云服务器和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。