Unix/Linux内存管理
1 内存分配和回收的函数(运算符)
STL -> 自动分配、自动回收
|
C++ -> new 分配 delete 回收
|
C语言 -> malloc()分配 free()回收
|
Unix系统函数 -> brk() sbrk()
|
Unix系统函数 -> mmap() munmap() 用户层
---------------------------------------
Unix系统函数 -> kmalloc() 内核层
UC 研究 6个函数
2 进程的内存空间
程序 - 存在硬盘上的可执行文件
进程 - 在内存中运行的程序
程序如果要运行,最基本的硬件:CPU和内存,CPU运算、内存存储数据。CPU只能直接访问内存,而不能直接访问硬盘。因此,硬盘上的程序如果要运行,首先要加载到内存中,内存中运行的程序叫 进程。
进程的内存空间:
1 代码区/段 - 存储函数的代码,函数指针就是函数在代码区的地址(首地址)。只读区
2 全局区 - 初始化的全局变量、static变量,读写都可以。
3 BSS段 - 未初始化的全局变量。BSS段在main()执行之前会自动清0。
4 堆区 - 也叫自由区,程序员全权掌控堆区。如果堆区的内存分配和回收出现问题,引发内存的泄漏。malloc() free()针对的就是堆区内存。
5 栈区 - 系统自动管理,函数的参数、局部变量(非static)。
6 只读常量区 - 字符串的字面值""、const修饰的全局常量,只读区,不能修改。
注:有些资料把只读常量区和代码区放在一起。
3 Unix/Linux内存的管理机制
Unix/Linux使用 虚拟内存地址技术,程序员所接触到的都不是真正的物理内存地址,而是虚拟内存地址。
每个进程都有0-4G的虚拟内存地址,本质上就是一个整数。这个整数先天是不能存储数据,否则引发 段错误。虚拟内存地址只有映射了物理内存/硬盘文件后,才能存储数据。
虚拟内存地址 本身不占用物理内存,但映射以后就占用物理内存/硬盘文件。
虚拟内存地址分为用户空间和内核空间,0-3G是用户空间,3G-4G是内核空间。用户空间不能直接访问内核空间,但可以通过系统提供的函数进入内核空间。
内存地址的基本单位是字节,内存映射的基本单位是内存页,一个内存页 4096字节(4k)。内存页可以用 getpagesize()函数获取,主流的操作系统内存页都是4K。
内存中各个区域的排列次序:
代码区
只读常量区
全局区
BSS段
堆区
栈区
堆区和栈区 距离非常远,堆区靠近BSS段,而栈区 靠近3G的位置。
段错误的常见原因:
1 使用了没有映射的虚拟内存地址,比如NULL。
2 对内存执行了没有权限的操作(修改只读区)。
Linux系统中,几乎一切都可以看成文件。
/proc目录就是对应内存中的进程。每个进程都有进程的PID,用ps -aux可以查看进程的信息。/proc/PID 目录就是进程对应的文件。
使用cat命令可以查看内存页的信息:
cat /proc/PID/maps
字符串常见的操作:
string.c (非常重要)
malloc()和free() - C程序员分配回收内存
malloc()分配内存时,系统会额外占用一些空间,用于存储一些附加信息。比如free()就需要附加信息判断释放内存到哪里结束。
malloc()只有在第一次时需要映射内存,一次映射33个内存页,如果用完了,才会再次映射。
如果malloc()申请的内存 超过33个内存页,系统会映射 稍多一点的内存。
1 内存分配和回收的函数(运算符)
STL -> 自动分配、自动回收
|
C++ -> new 分配 delete 回收
|
C语言 -> malloc()分配 free()回收
|
Unix系统函数 -> brk() sbrk()
|
Unix系统函数 -> mmap() munmap() 用户层
---------------------------------------
Unix系统函数 -> kmalloc() 内核层
UC 研究 6个函数
2 进程的内存空间
程序 - 存在硬盘上的可执行文件
进程 - 在内存中运行的程序
程序如果要运行,最基本的硬件:CPU和内存,CPU运算、内存存储数据。CPU只能直接访问内存,而不能直接访问硬盘。因此,硬盘上的程序如果要运行,首先要加载到内存中,内存中运行的程序叫 进程。
进程的内存空间:
1 代码区/段 - 存储函数的代码,函数指针就是函数在代码区的地址(首地址)。只读区
2 全局区 - 初始化的全局变量、static变量,读写都可以。
3 BSS段 - 未初始化的全局变量。BSS段在main()执行之前会自动清0。
4 堆区 - 也叫自由区,程序员全权掌控堆区。如果堆区的内存分配和回收出现问题,引发内存的泄漏。malloc() free()针对的就是堆区内存。
5 栈区 - 系统自动管理,函数的参数、局部变量(非static)。
6 只读常量区 - 字符串的字面值""、const修饰的全局常量,只读区,不能修改。
注:有些资料把只读常量区和代码区放在一起。
3 Unix/Linux内存的管理机制
Unix/Linux使用 虚拟内存地址技术,程序员所接触到的都不是真正的物理内存地址,而是虚拟内存地址。
每个进程都有0-4G的虚拟内存地址,本质上就是一个整数。这个整数先天是不能存储数据,否则引发 段错误。虚拟内存地址只有映射了物理内存/硬盘文件后,才能存储数据。
虚拟内存地址 本身不占用物理内存,但映射以后就占用物理内存/硬盘文件。
虚拟内存地址分为用户空间和内核空间,0-3G是用户空间,3G-4G是内核空间。用户空间不能直接访问内核空间,但可以通过系统提供的函数进入内核空间。
内存地址的基本单位是字节,内存映射的基本单位是内存页,一个内存页 4096字节(4k)。内存页可以用 getpagesize()函数获取,主流的操作系统内存页都是4K。
内存中各个区域的排列次序:
代码区
只读常量区
全局区
BSS段
堆区
栈区
堆区和栈区 距离非常远,堆区靠近BSS段,而栈区 靠近3G的位置。
段错误的常见原因:
1 使用了没有映射的虚拟内存地址,比如NULL。
2 对内存执行了没有权限的操作(修改只读区)。
Linux系统中,几乎一切都可以看成文件。
/proc目录就是对应内存中的进程。每个进程都有进程的PID,用ps -aux可以查看进程的信息。/proc/PID 目录就是进程对应的文件。
使用cat命令可以查看内存页的信息:
cat /proc/PID/maps
字符串常见的操作:
string.c (非常重要)
malloc()和free() - C程序员分配回收内存
malloc()分配内存时,系统会额外占用一些空间,用于存储一些附加信息。比如free()就需要附加信息判断释放内存到哪里结束。
malloc()只有在第一次时需要映射内存,一次映射33个内存页,如果用完了,才会再次映射。
如果malloc()申请的内存 超过33个内存页,系统会映射 稍多一点的内存。