虚拟内存复习
我们都知道虚拟内存的目的是为了让每个进程在运行的时候都觉得自己运行在一个独立并且连续的内存空间上,并且32位的机器其大小是2^32大小,那么64位是不是就是2^64这么大呢?
可以看到,64位的机器其虚拟内存大小为2^48次,为256T,这256T分配在2^64大小的两端,内核和用户各占据128T。在接下来的讨论中,我们只针对32位linux系统进行探讨。
如上图所示为一个虚拟内存的结构图,对于用户态的每一块我们都大致有过了解,用户态从高地址到低地址依次为:
- Environment Variables: 环境变量
- Command-line arguments: 命令行参数
- Stack: 程序运行栈
- Memory Mapping Segment: 一些情况的mmap映射的内存,和动态链接库
- Heap: 堆
- BSS Segment(.bss): 未初始化的全局或者静态变量
- Data Segment(.data): 已初始化的全局或者静态变量
- Text Segment(.init,.text,.rodata): 代码段
而内核态从高地址到低地址依次为:细节不做详细介绍,可能讲不完,感兴趣的可以自己去查阅一下
- High memory: 多级页表翻译
- Temporary Kernel Mapping: 临时映射
- Persistent Kernel Mapping: 持久映射
- Vmalloc Area loremap Area: vmalloc区域
- normal memory: 线性映射区域,不需要进行地址翻译,而可以直接通过固定偏移量来计算。
- Mem_map:
- Kernel Image:
- PGD,
- ...
- 问题:为什么会有High memory的存在,是不是无论什么情况下都会存在。
c++ 内存布局
下述的结论都可能和编译器的类型以及版本相关,下述都是基于GNU 编译器,g++ 4.x.x 做过的验证
非继承下的对象模型
在一个非继承的对象中,可能包含数据成员和函数,而细分的话可以是如下这些
- 数据成员:
- Static member data
- Non static member data
- 成员函数
- Static function
- Non static function
- Virtual function
class Base {
public:
Base();
virtual ~Base();
void Func();
static void StaticFunc();
virtual void VirtualFunc();
private:
int base_i_;
static int static_base_i_;
};
vptr只有在存在有虚函数的对象中才会存在,其指向vtable,而vtable中的第一个指向的地址退一个就是指向 type_info的地址,type_info里面保存了这个对象的相关信息,用于实现RTTI(runtime type