【初探】内存管理知多少


【初探】内存管理知多少?

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. 参考资料

    1. 《C专家编程》
    1. 《计算机操作系统》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值