C内存简析
来源:互联网 发布:阿里云服务器优点 编辑:程序博客网 时间:2024/06/06 02:09
1:内存分配
32位操作系统支持4GB内存的连续访问,但通常把内存分为两个2GB的空间,每个进程在运行时最大可以使用2GB的私有内存(0x00000000—0x7FFFFFFF)。至于高端的2GB内存地址(0x80000000—0xFFFFFFFF),操作系统一般内部保留使用,即供操作系统内核代码使用。每个进程都能看到自己的2GB内存以及系统的2GB内存,但是不同进程之间是无法彼此看到对方的。
2:虚拟内存
虚拟内存的基本思想是:用廉价但缓慢的磁盘来扩充快速却昂贵的内存。所有进程共享机器的物理内存,当内存使用完时就用磁盘保存数据。在进程运行时,数据在磁盘和内存之间来回移动。在进程执行过程中,操作系统负责具体细节,使每个进程都以为自己拥有整个地址空间的独家访问权。这个幻觉是通过“虚拟内存”实现的。内存管理硬件负责把虚拟地址翻译为物理地址,并让一个进程始终运行于系统的真正内存中,应用程序员只看到虚拟地址,并不知道自己的进程在磁盘与内存之间来回切换。
3:内存的使用
一、栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。
二、堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
三、全局区(又叫静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
四、常量区(又叫文字常量区):常量字符串就放在这里。程序结束后由系统释放。
五、程序代码区:存放函数体的二进制代码。(请注意是函数体)
有时候对一个进程的内存空间在逻辑上也可简单的划分为三个部分:代码区、静态数据区和动态数据区。
动态数据区一般就是“堆栈”。“栈”和“堆”虽然都属于动态数据区,但确是不同的东西,栈是一种线性结构,而堆是一种链式结构。进程中的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互补干扰的。堆和栈可以分别通过“基地址”和“栈顶”地址来描述。
关于堆的创建方式,大家可以看一下相关的C语言书籍,内容也通俗易懂,这里不再一一介绍
来看一个网上很流行的经典例子:
main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10); 堆
p2 = (char *)mall0c(20); 堆
}
4:堆栈的相关特性栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
实际上这些空闲内存碎片存在的方式有两种:a.内部碎片 b.外部碎片 。
内部碎片的产生:因为所有的内存分配必须起始于可被 4、8 或 16 整除(视处理器体系结构而定)的地址或者因为MMU的分页机制的限制,决定内存分配算法仅能把预定大小的内存块分配给客户。假设当某个客户请求一个 43 字节的内存块时,因为没有适合大小的内存,所以它可能会获得 44字节、48字节等稍大一点的字节,因此由所需大小四舍五入而产生的多余空间就叫内部碎片。
外部碎片的产生: 频繁的分配与回收物理页面会导致大量的、连续且小的页面块夹杂在已分配的页面中间,就会产生外部碎片。假设有一块一共有100个单位的连续空闲内存空间,范围是0~99。如果你从中申请一块内存,如10个单位,那么申请出来的内存块就为0~9区间。这时候你继续申请一块内存,比如说5个单位大,第二块得到的内存块就应该为10~14区间。如果你把第一块内存块释放,然后再申请一块大于10个单位的内存块,比如说20个单位。因为刚被释放的内存块不能满足新的请求,所以只能从15开始分配出20个单位的内存块。现在整个内存空间的状态是0~9空闲,10~14被占用,15~24被占用,25~99空闲。其中0~9就是一个内存碎片了。如果10~14一直被占用,而以后申请的空间都大于10个单位,那么0~9就永远用不上了,变成外部碎片。
阅读全文
0 0
- C内存简析
- C/C++内存管理简析
- c内存
- C内存
- C 内存
- C-内存
- 【C/C++】内存对齐
- 【c/c++】内存地址
- C内存—>内存分配
- 【基础C&C++】内存函数
- 内存相关(C/C++)基础知识
- C++/C有关内存思考题
- 内存错误(C/C++)
- 【C】C语言内存函数
- c++/c的内存管理机制
- 【C/C++】C++内存管理
- C/C++ 内存管理
- C中的内存对齐
- jmeter 前置处理器提取用户cookie信息 比如jsessionid
- 文件的权限和访问控制列表(ACL)
- 硬链接和软连接
- 短信验证的实现
- Watching TV Gym101498A
- C内存简析
- 今天给大家讲一些JS的东西,同时也是我们日常看到的APP当中很常见的一个模块,拖拽标题
- Dimens适配与布局适配
- 短信验证
- recycleview+okhttp请求数据
- 线性表的链式表示和实现
- PullToRefresh添加轮播图为头布局
- 链表题_1
- Android 仿萤石客户端横向滚动时间轴