C语言之内存管理

1、堆和栈

1.1 堆栈申请释放不同

栈由操作系统自动进行分配和释放,一般用于存储函数的局部变量(非static修饰的)、参数等,效率较高。

堆一般由程序员手动进行申请和释放,例如使用malloc函数进行申请,在使用完成后,free函数进行释放,效率相比于栈教低。

1.2 堆栈生命周期

栈上分配的内存只在特定的作用域下有效,函数执行完成后,内存会自动释放。要避免返回局部变量的指针。

堆上分配的内存需要手动释放,如果未手动释放可能造成内存泄漏等问题,这部分内存将在程序结束时才会被操作系统回收,造成系统资源的浪费。

1.3 生长方向

栈的分配方式是向下的,从高地址向低地址。

堆的分配方式与栈相反,从低地址向高地址。

c语言内存分区示意图

1.4 空间大小

栈通常具有固定的大小限制,在不同的操作系统和编程语言中有所不同,但通常较小,一般未几MB

堆的大小比栈要大的多,没有固定大小限制。由操作系统和物理内存的限制决定,理论上可以非常大,受系统总体内存和虚拟内存大小的限制。

1.5 是否会产生碎片

栈遵循先进后出的原则,不会有内存块从栈中弹出,不会产生碎片。

堆是通过动态分配方式进行分配和释放(比如mallocfreenewdelete),频繁的申请和释放可能引发内存碎片问题。

1.6 使用场景

栈适合存储局部变量和函数调用信息等轻量级数据。

堆适合存储需要动态分配和释放的数据结构、大对象或者在编译时大小未知的数据。


2、内存碎片

2.1 内存碎片的定义

内存碎片指的是分散在内存中的未被使用的小块内存空间。它们可能存在于堆或者虚拟内存中,是由于内存分配和释放操作导致的。内存碎片可分为外部碎片和内部碎片。

2.2 外部碎片

外部碎片是指未分配给任何对象的内存块,它们可能位于已分配内存块之间或者内存区域的末尾。

外部碎片的存在可以阻碍大块连续内存空间的分配,即使总体上有足够的未分配内存,但由于无法找到足够大且连续的内存块,导致内存分配失败或者效率降低。

2.3 内部碎片

内部碎片是指已经分配给对象但未被使用的内存部分。这种情况通常发生在对象的大小不是内存分配单位的整数倍时(如内存分配单位是字节,但对象大小是其整数倍+1)。

内部碎片不会影响到未分配内存的连续性,但是会导致内存使用效率的降低,因为一部分已经分配的内存实际上并没有被有效利用。

2.4 内存碎片的解决方法

段页式管理:采用虚拟内存管理技术,将物理内存划分为不同的页或段,以更灵活地管理和分配内存空间,减少碎片化。

使用内存池:通过分配一定数量的内存块,由内存池来管理分配和回收,减少频繁的内存分配和释放,从而减少碎片化。


3、内存池

3.1 内存池定义

内存池(Memory Pool)是一种动态内存分配与管理技术。在c语言中通常使用malloc函数申请内存,free函数释放内存。在c++中通过new申请内存,delete释放内存。当程序长时间运行时,申请内存的大小不确定以及频繁的使用这种方式会造成大量的内存碎片,导致操作系统的资源利用效率降低。内存池的基本思想是预先分配一定数量的内存块,并在需要时直接从已分配的内存块中获取,而不是每次请求内存时都进行动态的内存分配和释放操作。

3.2 内存池的特点和优势

3.2.1 预分配内存

内存池会在程序初始化或者需要大量内存分配时预先分配一定数量的内存块,这些内存块可以是固定大小的,也可以是多种大小的,根据具体的应用场景决定。

3.2.2 减少碎片化

通过预分配和重复利用内存块,内存池可以减少内存碎片的产生,因为每次分配的内存块大小是固定的或者有限的几种选择。

3.2.3 提高性能

内存池可以显著提高内存分配和释放的效率,特别是在需要频繁分配和释放小块内存时。这是因为内存池管理的内存块通常是连续的,分配操作可以是常数时间复杂度,而不会受到外部碎片的影响。

3.2.4 避免内存泄漏

由于内存池在程序生命周期内保持管理,通常不会出现常见的内存泄漏问题,即已分配但无法释放的内存块。

3.2.5 应用场景

内存池特别适合于需要高效管理内存且频繁进行内存分配和释放的应用,如网络服务器、数据库管理系统、游戏引擎等。


4、虚拟内存管理

4.1 什么是虚拟内存

虚拟内存是操作系统提供给每个进程的抽象内存空间,它使得每个程序都能够拥有自己的地址空间,而不受物理内存大小的限制。虚拟内存由物理内存(RAM)和硬盘(或其他存储设备)上的交换文件组成。

4.2 虚拟内存管理的核心概念

4.2.1 地址转换

虚拟内存管理技术通过地址转换机制将进程使用的虚拟地址映射到物理内存或者交换文件上的对应位置。这种映射使得进程可以使用比物理内存更大的地址空间。

虚拟内存与物理内存映射

4.2.2 页面调度

为了优化内存使用和响应速度,虚拟内存管理使用页面调度(Page Replacement)算法(常见的算法包括最优页面置换算法、先进先出(FIFO)算法、最近未使用(LRU)算法等)来决定哪些页面需要置换出物理内存,哪些页面需要从硬盘调入到物理内存中。

4.2.3 页面大小

虚拟内存管理还涉及到页面大小的选择。典型的页面大小可以是4KB或者更大,这取决于硬件和操作系统的设定。

4.3 虚拟内存管理的优势

4.3.1 更大的地址空间

虚拟内存允许每个进程访问远超过物理内存大小的地址空间,这对于运行大型应用程序或者多任务处理至关重要。

4.3.2 内存保护

每个进程拥有自己的虚拟地址空间,使得操作系统能够实施内存保护机制,防止进程越界访问或者恶意修改内存数据。

4.3.3 便于内存共享

虚拟内存管理技术允许多个进程共享同一个物理内存页面,从而减少内存使用和提高系统的效率。

  • 35
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值