【初探】内存管理知多少
2016-06-14 18:05
239 查看
日期:20160614
作者:i.sshe
https://github.com/isshe
1.2 什么是虚拟内存?
1.3 什么内存泄漏?如何检测?如何避免?
1.4 什么是内存溢出?
2.2 什么是碎片?什么是外碎片?什么是内碎片?
2.3 什么是ELF?
2.4 如何知道系统中进程能分配多大的内存?
2.5 什么是动态链接?什么是静态链接?
优点:
没有外碎片,内碎片不大于一页。
缺点:
程序全部装入内存;
要求相应的硬件支持。
段式管理:
把程序按内容或过程函数关系分段,每个段有自己的名字。
优点:
可以根据不同的段采用不同的保护;
可以以段为单位进行共享;
可以分别编写和编译;
缺点:
会产生碎片;
段页式管理:
主存分段,段内再分页。
内存分配时,是以页为单位。
每取一次数据都要访问3次内存。
优点:
内存利用率更高;
以上种管理方式的优点都有;
缺点:
需要硬件支持;
占用内存更多;
执行速度有所下降;
程序使用的虚拟内存中的内容就被载入物理内存,物理内存中一段时间不用的数据,会被移动到磁盘,省下的物理内存用于其他地方。
优点:
扩大地址空间;
内存保护。每个进程运行在各自的虚拟内存中,互不干扰。
内存分配公平。每个进程都可以得到同样大小的虚拟内存。
进程通信可采用虚拟共享的方式。
缺点:
虚拟内存的管理需要各种数据结构,需要额外的内存。
虚拟地址和物理地址的转换需要时间。
数据的换入换出需要磁盘I/O,需要大量时间。
内存泄漏是最难调试发现的问题之一。
检测方法:
方法一:
使用命令swap(或其他netstat、vmstat)观察是否有内存泄漏。(1~2分钟内执行5次左右)
确定可疑进程。(可使用ps命令查看进程大小,多次执行,观察内存增长的进程)
避免方法:
调用malloc()分配内存后,注意用对应的free()释放内存。
必要时,使用alloca()分配动态内存:当离开调用alloca()的函数时,内存会被释放。
产生原因:
解引用一个未初始化或非法值的指针。(p是指针,*p即为解引用)
解引用一个空指针。
未得到正确权限时进行访问。(如:写只读的文本段)
堆或栈空间耗尽。
越界访问:
同一内存释放两次;
释放不是malloc分配的内存;
释放使用中的内存;
内碎片:分配给某程序的内存空间,程序不使用,但系统也无法再利用(直到程序结束)。
外碎片:空间太小,无法分配给任何的进程,这些小空间即外碎片。
ELF:原意为“Extensible Linker Format, 可拓展链接器格式”,现在表示为“Executable and Linking Format, 可执行文件和链接格式”
动态链接:运行时载入所需函数库。(可执行文件只包含文件名,运行时载入器根据文件名找到函数库)
优点:
可执行文件体积小;
能更有效地利用磁盘空间;
函数库升级更容易;
缺点:
运行速度稍慢;
linux下动态链接后缀为.so, 静态链接后缀为.a;
-l 选项链接函数库;
-L 选项指定目录;
静态链接时要注意顺序的问题,否则会遇到各种“未定义”;(被调用的写后面,调用的写前面)
《计算机操作系统》
作者:i.sshe
https://github.com/isshe
【初探】内存管理知多少?
1. 基础问题
1.1 常见的内存管理方式有哪些?1.2 什么是虚拟内存?
1.3 什么内存泄漏?如何检测?如何避免?
1.4 什么是内存溢出?
2. 拓展问题
2.1 什么是段错误?2.2 什么是碎片?什么是外碎片?什么是内碎片?
2.3 什么是ELF?
2.4 如何知道系统中进程能分配多大的内存?
2.5 什么是动态链接?什么是静态链接?
3. 基础问题解答
3.1 常见的内存管理方式有哪些?
页式管理:将一个进程的逻辑地址空间划分成若干个大小相等的部分,每个部分称为页。优点:
没有外碎片,内碎片不大于一页。
缺点:
程序全部装入内存;
要求相应的硬件支持。
段式管理:
把程序按内容或过程函数关系分段,每个段有自己的名字。
优点:
可以根据不同的段采用不同的保护;
可以以段为单位进行共享;
可以分别编写和编译;
缺点:
会产生碎片;
段页式管理:
主存分段,段内再分页。
内存分配时,是以页为单位。
每取一次数据都要访问3次内存。
优点:
内存利用率更高;
以上种管理方式的优点都有;
缺点:
需要硬件支持;
占用内存更多;
执行速度有所下降;
3.2 什么是虚拟内存?
基本思路: 用廉价、缓慢的磁盘来扩充快速、昂贵的内存。程序使用的虚拟内存中的内容就被载入物理内存,物理内存中一段时间不用的数据,会被移动到磁盘,省下的物理内存用于其他地方。
优点:
扩大地址空间;
内存保护。每个进程运行在各自的虚拟内存中,互不干扰。
内存分配公平。每个进程都可以得到同样大小的虚拟内存。
进程通信可采用虚拟共享的方式。
缺点:
虚拟内存的管理需要各种数据结构,需要额外的内存。
虚拟地址和物理地址的转换需要时间。
数据的换入换出需要磁盘I/O,需要大量时间。
3.3 什么内存泄漏?如何检测?如何避免?
内存泄漏:未释放不再使用的内存。内存泄漏是最难调试发现的问题之一。
检测方法:
方法一:
使用命令swap(或其他netstat、vmstat)观察是否有内存泄漏。(1~2分钟内执行5次左右)
确定可疑进程。(可使用ps命令查看进程大小,多次执行,观察内存增长的进程)
避免方法:
调用malloc()分配内存后,注意用对应的free()释放内存。
必要时,使用alloca()分配动态内存:当离开调用alloca()的函数时,内存会被释放。
3.4 什么是内存溢出?
内存溢出(out of memory):是指程序在申请内存时,没有足够的内存空间供其使用。例如C语言中声明int类型,赋值long型就有可能会溢出。4. 拓展问题解答
4.1 什么是段错误?
段错误(segmentation fault(core dumped))产生原因:
解引用一个未初始化或非法值的指针。(p是指针,*p即为解引用)
int *p = null; *p = 22;
解引用一个空指针。
未得到正确权限时进行访问。(如:写只读的文本段)
堆或栈空间耗尽。
越界访问:
p = malloc(10); p[10] = 10;
同一内存释放两次;
释放不是malloc分配的内存;
释放使用中的内存;
4.2 什么是碎片?什么是外碎片?什么是内碎片??
碎片:由于内存分配造成的小空隙的无法被使用的内存。内碎片:分配给某程序的内存空间,程序不使用,但系统也无法再利用(直到程序结束)。
外碎片:空间太小,无法分配给任何的进程,这些小空间即外碎片。
4.3 什么是ELF?
目标文件和可执行文件可以有几种不同的格式,ELF是其中一种(绝大多数SVr4系统中采用)。【BSD UNIX中是:a.out格式】ELF:原意为“Extensible Linker Format, 可拓展链接器格式”,现在表示为“Executable and Linking Format, 可执行文件和链接格式”
4.4 如何知道系统中进程能分配多大的内存?
#include <stdio.h> #include <stdlib.h> int main(void) { int mb=0; while(malloc(1<<20)) //1<<20可以改其他。 { mb++; } printf("mb = %d\n", mb); return 0; }
4.5 什么是动态链接?什么是静态链接?
静态链接:函数库的一份拷贝是可执行文件的一部分。(并不是整个函数库,只是需要的函数!)动态链接:运行时载入所需函数库。(可执行文件只包含文件名,运行时载入器根据文件名找到函数库)
优点:
可执行文件体积小;
能更有效地利用磁盘空间;
函数库升级更容易;
缺点:
运行速度稍慢;
linux下动态链接后缀为.so, 静态链接后缀为.a;
-l 选项链接函数库;
-L 选项指定目录;
静态链接时要注意顺序的问题,否则会遇到各种“未定义”;(被调用的写后面,调用的写前面)
5. 参考资料
《C专家编程》《计算机操作系统》
相关文章推荐
- 数据库链接字符串查询网站
- 页面缓存:内存和文件之间的那些事
- 如何获得外部优质网站的链接pr
- Lua的内存管理浅析
- mySQL占用虚拟内存达8百多兆问题解决思路
- html链接与文本标签们
- 详解链接的rel与target区别
- 一个链接按两种方式打开两个网址的方法
- c语言内存泄露示例解析
- MS SQL Server2014链接到MS SQL Server 2000的解决方案及问题处理
- PHP检测链接是否存在的代码实例分享
- php自动给网址加上链接的方法
- 用CSS实现链接的虚线下划线效果
- ASP为字符串中的网址自动加上链接
- 跟我学习JScript的Bug与内存管理
- 解决js函数闭包内存泄露问题的办法
- 获取内联和链接中的样式(js代码)
- ASP.NET列出数据库活跃链接的方法
- JavaScript来实现打开链接页面的简单实例
- JQuery 实现在同一页面锚点链接之间的平滑滚动