Unix系统的内存管理

1、什么是内存?

内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。内存(Memory)也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。 内存是由内存芯片、电路板、金手指等部分组成的。

2、什么是内存管理?

内存管理是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。

3、一个进程的内存空间划分

3.1 进程的定义

有些人会将进程、线程、程序这几个概念混淆。

程序是代码编译链接的产物,是存储在硬盘上的文件,程序是静止的,没有运行。

运行起来的程序就是进程,是在内存中运行的程序,也就是把程序加载到了内存中,是运行的。即程序是在硬盘上的,进程是在内存里的。

一个程序可以运行出多个进程,一个进程也可以用多个程序。内存中的每个进程,都在/proc目录下建立一个目录,目录名就是进程ID(PID),进程结束,目录消失。这个目录就是进程的文件方式。cat /proc/进程ID/maps 查看进程的内存分配情况。getpid()函数获取当前进程的ID。

线程这里只做简单的介绍,形象一点,进程是老板,线程是老板的员工。

3.2 进程的内存空间划分

一个进程的内存空间可划分为以下部分:

1、代码区 :用于存放代码(函数)的区域,是只读区。函数指针就是指向代码区的地址。

2、全局区 :用于存放全局变量的区域和静态(static)变量。

3 、BSS段 :用于存放未初始化的全局变量的区域。BSS段在主函数执行之前会清零。

4、栈区(堆栈stack) :用于局部变量的区域,包括函数的参数和非static的局部变量。系统自动管理栈区。

5、堆区(heap):也叫自由区,程序员唯一可以控制的区域,通常内存分配、回收都是在堆区。malloc,free都是在堆区。堆区的内存系统完全不管,程序员全权管理。(进程结束时,所有内存会自动释放)。

6、只读常量区:存放字符串字面值“asd”和const修饰的全局变量。这个区域也是只读区,很多书把只读常量区并入代码区。

地址从小到大排列顺序:

1、代码区

2、只读常量区

3、全局区

4、BSS段

5、堆区

6、栈区

4、虚拟内存地址空间的机制

Unix/Linux使用虚拟内存地址的方式管理内存,每个进程先天都有0-(4G-1)的虚拟内存地址空间,本质就是整数(编号)。虚拟内存地址本身不能储存任何数据,必须映射到物理内存或者硬盘上的文件后 才能存储数据,否则引发段数据,目前程序员接触的都是虚拟内存地址。

虚拟内存的地址分为用户层和内核层,用户层0-3G,3G-4G是内核层(可以设置),用户层不能直接访问内核层,通过系统函数可以。

内存的基本单位是字节,内存地址是逐字节的,但是内存映射的基本单位不是一个字节,是4096字节(4k),叫一个内存页。函数getpagesize()可以查看内存页的大小。

如果地址弄错了,则会引发段错误,常见的段错误原因有两点:

1、使用没有映射的虚拟内存地址存储数据/获取数据。

2、对没有权限的区域进行操作,比如修改只读区。

5、内存管理的相关函数

1、malloc()函数和free()函数

void* malloc(size_t size)

size是要分配的字节数,返回分配内存的首地址。

内存分配的函数要做两件事情:

1、分配虚拟内存地址

2、映射物理内存/硬盘文件--第一次映射,后面用完了再映射。malloc申请小块内存时,一次映射33个内存页,用完后再继续映射,申请大块内存时,(超过31个内存页),会映射比申请稍微多一点的内存页。

malloc()函数除了分配正常的内存空间,还需要额外开辟一些空间,用于

存储一些附加信息,比如分配内存的大小。

free()一定会释放虚拟内存地址,以便虚拟内存地址可以循环利用,不一定

解除映射,超过33个内存页的部分会释放,最后33个内存页不释放,直到

进程结束时释放。

2、sbrk()函数和brk()函数

sbrk()和brk()系统的底层会维护一个位置,通过位置的移动完成内存的分配与回收。映射内存时,以一个内存页作为基本单位。

void *sbrk(int increment)

参数increment是增量,增量为正数时,分配内存,增量为负数时,回收内存

执行成功返回之前的地址,失败返回-1.增量为0,取当前位返回移动之前的位置(可用内存的首地址),这个返回值对于增量为负数的情况没有意义。sbrk()函数与malloc()的实现原理完全不同。

sbrk()在分配内存时很方便,但是回收内存时很麻烦。一般用brk()回收内存。

int brk(void* addr),成功返回0,失败返回-1。

brk()的使用方式就是直接传递一个地址过来,做新位置。brk()必须和sbrk()结合使用,获得第一个位置。

3、mmap()和munmap() ---Unix的系统函数,更贴近底层

void* mmap(void* addr,size_t length,int prot,int flags,int fd,off_t offset)

参数addr可以指定映射的首地址,一般为0,交给内核指定。length是分配内存的大小,映射时以页为单位。prot是分配内存的权限,一般用PROT_READ|PORT_WRITE。flags时标识,通常包括以下三个:

MAP_SHARED MAP_PRIVATE :二选一,指明映射的内存是否共享,MAP_SHARED只对映射文件有效。

MAP_ANONYMOUS:映射物理内存,默认映射文件。

fd是文件描述符,在映射文件时有用

offset是文件的偏移量,指定映射文件从哪里开始。

映射物理内存时,fd和offset给0即可

返回成功返回首地址,失败返回MAP_FAILED==(void*)-1

int munmap(void* addr,size_t length);

取消映射。

需要说明的是,这三对函数都能完成内存的分配与回收,到底应该用哪一个需要根据实际情况来决定。

系统调用

用户层的程序不能直接访问内核层,系统的核心功能必须通过内核层控制。因此,系统提供了一系列的函数,允许用户层的程序通过函数进入内核层,从而完成功能。这些函数,统称为系统调用(System call)。

Unix系统的内存管理相关推荐

  1. UNIX再学习 -- 内存管理

    C 语言部分,就一再的讲内存管理,参看:C语言再学习 -- 再论内存管理  UNIX.Linux 部分还是要讲,足见其重要. 一.存储空间布局 1.我们先了解一个命令 size,继而引出我们今天要讲的 ...

  2. Linux高级运维(一)系统的内存管理

    知识点参考IBM 一.为什么必须管理内存 内存管理是计算机编程最基本的领域之一.在许多脚本语言中,您不必担心如何管理内存,但这并不会使内存管理变得不那么重要.了解内存管理器的能力和局限对于有效编程至关 ...

  3. 【Linux 内核】Linux 内核源码几个重要的入口源文件及函数介绍 ( 系统初始化 | 内存管理 | 虚拟文件系统 | 网络管理 )

    文章目录 一.系统初始化 二.内存管理 三.虚拟文件系统 四.网络管理 一.系统初始化 系统初始化 的入口源码是 " linux-5.6.18\init\ " 目录下的 main. ...

  4. Linux系统基础——内存管理

    Linux系统内存管理 特此说明: 刘超的趣谈linux操作系统是比较重要的参考资料,本文大部分内容和所有图片来源于这个专栏. 1 物理内存 物理内存根据 NUMA 架构分节点.每个节点里面再分区域. ...

  5. windows 映射文件会释放内存吗_Windows系统共享内存管理

    一 进程逻辑空间 物理空间 ​ 如上图所示,每个进程都有自己的逻辑空间,这些逻辑空间,会被映射到具体的物理空间中. 每个进程的逻辑空间都是彼此隔离,相互独立不受干扰的. 但是他们都会被映射到同一个物理 ...

  6. Linux 及其它类 Unix 系统的系统服务管理和控制程序(初始化系统/init system)简单梳理

    文章目录 一.Linux 的启动过程 二.初始化程序 (一)System V init (二)Upstart init (三)systemd (四)Launchd (五)Epoch (六)Mudar ...

  7. UNIX再学习 -- 死磕内存管理

    malloc/free简化实现:malloc 和 sbrk 关系:虚拟内存机制. 一个内存管理 C 语言部分讲,UNIX部分讲,Linux部分还讲,死磕到底!! 一.mallc/free简化实现 上篇 ...

  8. 鸿蒙系统内存管理,嵌入式系统内存管理-鸿蒙HarmonyOS技术社区-鸿蒙官方战略合作伙伴-51CTO.COM...

    1.概述 操作系统的内存管理功能用于向操作系统提供一致的地址映射功能和内存页面的申请.释放操作.在嵌入式实时系统中,内存管理根据不同的系统,有不同的策略,对于有些系统支持的虚拟内存管理机制,对于另外一 ...

  9. 系统内存管理介绍,内存申请及回收流程

    目录 系统申请以及回收内存 占用块和空闲块 系统的内存管理 可利用空间表 分配存储空间的方式 空间分配与回收过程产生的问题 边界标识法内存碎片合并 分配算法 回收算法 伙伴系统管理动态内存 可利用空间 ...

最新文章

  1. Linux脚本自动安装软件,一个快速自动安装Apache及其相关软件的Shell脚本
  2. 你以为 CSS 只是个简单的布局?装逼指南了解一下
  3. 围棋经典棋谱_秀秀老师:茶艺师也要学好围棋
  4. 【翻译】ANDROID KTX – 使用Kotlin进行Android开发
  5. redis新数据类型-HyperLogLog
  6. MATLAB实现控制鼠标移动和点击
  7. 雷赛控制卡可以用java写吗_运动控制卡应用编程技巧几招(2)
  8. treetable php,第105款插件:jquery.treetable.js的使用
  9. access简述报表的功能_报表的主要功能_access标签报表有什么作用
  10. python3中的sorted()函数
  11. 8.7. Enumerated Types
  12. 动作游戏的打击感和音效的关系
  13. PostGIS教程一:PostGIS介绍
  14. Microsoft.NET Framework 3.5Service Pack1下载Windows功能失败原因
  15. 最近玩喂喂我的小仓鼠吧,玩上瘾了……
  16. elasticsearch 生产级别深度优化
  17. 如何安装Ubuntu 20.04 LTS服务器的图文教程
  18. 手机如何压缩照片?压缩方法分享
  19. android gps距离计算器,计算器刷成安卓系统 刷系统千万别找设计师
  20. Scilab学习心得

热门文章

  1. 怎么把图片修改成600x800像素图片
  2. 【软考中级】多媒体应用设计师复习笔记第五章
  3. 微信素材--临时图文链接素材(有效期3天)
  4. 连分数matlab,浅谈指数分布的性质及其应用.doc
  5. PDF文件新建空白文档该如何操作
  6. 英语 | Day9、10 x 句句真研每日一句(三种结构、两个从句)
  7. Java 最常见 200+ 面试题全解析(基础必备)
  8. 【学习笔记+习题集】(树状数组)(9473字)
  9. [附源码]java毕业设计运动器材网上销售系统
  10. win10 SystemParametersInfo 设置屏保 不好使_黑科技学:抖音最近很火的时间罗盘屏保出电脑版了,实在太帅了...