目录
1、为什么需要管理内存呢?
电脑的内存资源有限,系统中运行的进程是无限的,所以说,电脑不能运行太多的进程,如果运行进程数量过多,则会出现电脑运行性能降低,甚至由于资源有限,新的进程不能正常运行。
2、何为内存管理?
内存管理就是系统管理每个运行进程之间的内存空间相互独立,可以正常地运行。
每个进程的空间地址分配机制都是已有的,每个进程在内核态和用户态各自有一个堆栈,当进程运行在用户态时,进程使用的时用户态的空间;当运行在在内核态时,使用的时内核态空间。
a:什么是内核态?什么是用户态?
简单的来说,内核态操作权限高,用户态的操作权限低。内核态可以直接操作系统系统的所有资源,比如操作各种硬件设备。用户态可以通过系统的API函数来进行操作硬件设备和内存。用户态和内核态的机制提供了操作系统的稳定性和可用性。
b:系统怎们管理内存?
系统通过虚拟内存_百度百科 (baidu.com)技术来管理内存,虚拟内存的工作原理、调度方法可参考百度百科介绍。虚拟内存机制相当于内存管家,主要做的事情有:(1)给每个进程分配独立的虚拟空间,每个进程间的内存地址互不影响。(2)实现虚拟空间地址到实际硬件物理地址的映射机制。(3)引入缺页异常机制实现内存的惰性分配。(4)进入swap机制,把不活跃的数据换到磁盘上。
虚拟地址和物理的映射关系由页表反应,页表相当于一张地图,内存管理单元收到CPU的虚拟地址后,通过查询页表可以确定对应的物理地址。关于具体介绍可参考40 张图解 | Linux 内存背后的那些神秘往事
有一篇介绍内存管理很好的文章见:真棒! 20 张图揭开内存管理的迷雾,瞬间豁然开朗
虚拟地址和物理地址形象的对应关系如下图所示:
虚拟地址到物理地址的映射挂关系只是内存管理单元MMU其中的一个的功能,它还有内存保护、中央处理器高速缓存的控制等功能。
3、基础知识介绍
系统中内存区域划分如下:
栈上申请的内存是连续的,内存由系统回收。堆上申请的内存不是连续,内存由程序员申请和释放,多次的申请和释放会造成内存碎片,内存碎片会影响系统运行的性能。
上面内存区各个分类介绍如下:
(1)内核空间:操作系统内核代码运行的内存空间。
(2)栈区:函数内部非静态局部变量,函数形参。
(3)内存映射段I/O:是将磁盘文件的数据映射到虚拟地址的内存,内存映射包含文件映射、动态映射、匿名映射,常用来实现进程间的通信。
(4)堆:堆是由程序员手段分配和释放,C++中分配内存的方式由new和malloc。new是操作符,可以重载,malloc是函数,可以重写。new分配内存是通过malloc实现,new比malloc使用更安全,支持自定义类型内存分配,区别可参考:经典面试题之new和malloc的区别_Datou_Nie的博客-CSDN博客_new和malloc的区别
(5)数据段:存储全局变量,静态变量(全局静态变量,局部静态变量),常量。
(6)代码段(程序段):存放程序执行代码的一段内存,该内存区域是程序运行前已经确定,并且内存区域通常属于只读,在代码段中可能包含一些只读常量。
使用注意:
堆栈在程序中使用最多,堆栈的区别有:(1)堆是由程序员分配和释放。栈是由系统分配释放。(2)堆分配效率比栈慢。(3)堆会存在内存碎片,影响机器性能,栈不会产生内存碎片。(4)堆的分配空间大,32位系统理论4G。栈内存空间小,一般位1M或2M,所以对一些较大数据量的存储,必须使用堆。(5)堆生长从低到高,即是从低地址到高地址分配;栈生长高到低。即从高地址到低地址分配。
4、C++中内存分区
C++中内存可以大致分为四个区:
(1)栈:生命周期是编译器自动释放。
(2)堆(malloc,new):生命周期是用户分配,用户释放。
(3)全局区(静态区):程序结束时释放。
(4)代码区
C++的内存分区属于系统内存分区的子集,尽管C++分区名跟系统内存分区名有的不一样,但描述的内存空间是一样的。
C++内存分区可参考:
C++ Basic 32 : 内存四区- 变量的生命周期是怎么管理的?_Techblog of HaoWANG的博客-CSDN博客