一、内存管理
硬件层次
内存结构管理
内核层次
内存映射
堆扩展
语言层次
c:malloc
c++:new
数据结构
STL 对多线程支持存在问题 对共享内存也存在问题 这俩个瓶颈
智能指针 在boost库中
1.Linux对内存的结构描述
1./proc/${pid}/ 存放进程运行时候所有的信息(包括内存结构)
任何程序的内存空间分成4个基本部分
1.代码区
2.全局栈区
3.堆
4.局部栈
进程查看 ps aue
自加载程序 /lib/ld-linux.so.X X是版本号。
在基于 GNU glibc 的系统上,包括所有 linux 系统,ELF 可执行二进制文件的运行自动导致程序加载器被加载并且运行。加载器搜索、加载程序所要使用的动态链接库。
2.理解程序的变量与内存空间的关系
结论:
1.内存分四个区.
2.各种变量对应存放区
3.堆栈是一种管理内存的数据结构.
4.查看程序的内存地址.
2.理解malloc的工作的原理
malloc使用一个数据结构(链表)维护分配空间
链表的构成:分配的空间/上一个空间数据/下一个空间/空间大小等信息.
对malloc分配的空间不要越界访问.因为容易破坏后台维护结构.
导致malloc/free/calloc/realloc不正常工作.
3.C++的new与malloc的关系
malloc new new[]
realloc new()
calloc new[]
free delete delete[]?
结论:new的实现使用的是malloc来实现的.
区别:new使用malloc后,还要初始化空间.
基本类型,直接初始化成默认值.
UDT类型,调用指定的构造器
delete调用free实现.
delete负责调用析构器.然后再调用free
new与new[]区别
new只调用一个构造器初始化.
new[]循环对每个区域调用构造器.
delete 与delete[]
4.函数调用栈空间的分配与释放
4.1.总结:
1.函数执行的时候有自己的临时栈.
2.函数的参数就在临时栈中.如果函数传递实参.则用来初始化临时参数变量.
3.通过积存器返回值.(使用返回值返回数据)
4.通过参数返回值.(参数必须是指针)
指针指向的区域必须事先分配.
5.如果参数返回指 针.参数就是双指针.
4.2.__stdcall __cdecl __fastcall
1.决定函数栈压栈的参数顺序.
2.决定函数栈的清空方式
3.决定了函数的名字转换方式.
5.far near huge指针
near 16
far 32
huge 综合
二.虚拟内存
问题:
一个程序不能访问另外一个程序的地址指向的空间.
理解:
1.每个程序的开始地址0x80084000
2.程序中使用的地址不是物理,而是逻辑地址(虚拟内存).
逻辑地址仅仅是编号.编号使用int 4字节整数表示.
4294967296
每个程序提供了4G的访问能力
问题:
逻辑地址与物理地址关联才有意义:过程称为内存映射.
背景:
虚拟内存的提出:禁止用户直接访问物理存储设备.
有助于系统的稳定.
结论:
虚拟地址与物理地址映射的时候有一个基本单位:
4k 1000 内存页.
段错误:无效访问.
合法访问:比如malloc分配的空间之外的空间可以访问,但访问非法.
三.虚拟内存的分配.
栈:编译器自动生成代码维护
堆:地址是否映射,映射的空间是否被管理.
1.brk/sbrk 内存映射函数
分配释放内存:
int brk(void *end);//分配空间,释放空间
void *sbrk(int size);//返回空间地址
应用:
1.使用sbrk分配空间
2.使用sbrk得到没有映射的虚拟地址.
3.使用brk分配空间
4.使用brk释放空间
理解:
sbrk(int size)
sbrk与brk后台系统维护一个指针.
指针默认是null.
调用sbrk,判定指针是否是0,是:得到大块空闲空间的首地址初始化指针.
同时把指针+size
否:返回指针void×(-1);
四.总结
智能指针
stl
new
malloc
brk/sbrk
异常处理
int brk(void*)
void *sbrk(int);
如果成功.brk返回0 sbrk返回指针
失败 brk返回-1 sbrk返回(void*)-1
Unix函数错误,修改内部变量:
errno
五.知识点
内存管理 从底层到上层分别有那些方式
C++中 new和malloc是怎么执行的;
Linux对内存的结构描述
系统是如何管理内存的
理解程序的变量与内存空间的关系
函数调用栈空间的分配和释放 函数看一下stacall.txt;
为什么提出虚拟内存的概念 安全;
内存映射
内存映射函数 brk和sbrk
虚拟内存
栈:编译器自动生成代码维护
堆:地址是否映射,映射的空间是否被管理.