[转帖]Linux内存管理基本概念

news/2024/11/15 17:29:39/文章来源:https://www.cnblogs.com/jinanxiaolaohu/p/18202584

最近在学习Linux系统的内存管理,小白一枚,零散从网上收集的一些笔记如下:

/proc目录提供了很多工具给我们查看当前内存情况

1. /proc/meminfo是什么

  1. $cat /proc/meminfo
  2. MemTotal: 2052440 kB //总内存
  3. MemFree: 50004 kB //空闲内存
  4. Buffers: 19976 kB //给文件的缓冲大小
  5. Cached: 436412 kB //高速缓冲存储器(http://baike.baidu.com/view/496990.htm)使用的大小
  6. SwapCached: 19864 kB //被高速缓冲存储用的交换空间大小
  7. Active: 1144512 kB //活跃使用中的高速缓冲存储器页面文件大小
  8. Inactive: 732788 kB //不经常使用的高速缓冲存储器页面文件大小
  9. Active(anon): 987640 kB //anon:不久
  10. Inactive(anon): 572512 kB
  11. Active(file): 156872 kB
  12. Inactive(file): 160276 kB
  13. Unevictable: 8 kB
  14. Mlocked: 8 kB
  15. HighTotal: 1177160 kB //The total and free amount of memory, in kilobytes, that is not directly mapped into kernel space.
  16. HighFree: 7396 kB // The HighTotal value can vary based on the type of kernel used.
  17. LowTotal: 875280 kB // The total and free amount of memory, in kilobytes, that is directly mapped into kernel space. used.
  18. LowFree: 42608 kB //The LowTotal value can vary based on the type of kernel
  19. SwapTotal: 489940 kB //交换空间总大小
  20. SwapFree: 450328 kB //空闲交换空间
  21. Dirty: 104 kB //等待被写回到磁盘的大小
  22. Writeback: 0 kB //正在被写回的大小
  23. AnonPages: 1408256 kB //未映射的页的大小
  24. Mapped: 131964 kB //设备和文件映射的大小
  25. Slab: 37368 kB //内核数据结构缓存的大小,可减少申请和释放内存带来的消耗
  26. SReclaimable: 14164 kB //可收回slab的大小
  27. SUnreclaim: 23204 kB //不可收回的slab的大小23204+14164=37368
  28. PageTables: 13308 kB //管理内存分页的索引表的大小
  29. NFS_Unstable: 0 kB //不稳定页表的大小
  30. Bounce: 0 kB //bounce:退回
  31. WritebackTmp: 0 kB //
  32. CommitLimit: 1516160 kB
  33. Committed_AS: 2511900 kB
  34. VmallocTotal: 122880 kB //虚拟内存大小
  35. VmallocUsed: 28688 kB //已经被使用的虚拟内存大小
  36. VmallocChunk: 92204 kB
  37. HugePages_Total: 0 //大页面的分配
  38. HugePages_Free: 0
  39. HugePages_Rsvd: 0
  40. HugePages_Surp: 0
  41. Hugepagesize: 2048 kB
  42. DirectMap4k: 10232 kB
  43. DirectMap2M: 899072 kB

Active: 1308168 kB = Active(anon): 1010416 kB + Active(file): 297752 kB
然后 Active(anon) 表示 anonymous pages,Active(file)表示 file-backed pages   (inactive 同理)

Active/inactive memory 是针对用户进程所占用的内存而言的,内核占用的内存(包括 slab )不在其中。
ACTIVE_ANON 和 ACTIVE_FILE,分别表示 anonymous pages 和 file-backed pages。用户进程的内存页分为两种:与文件关联的内存(比如程序文件、数据文件所对应的内存页)和与文件无关的内存(比如进程的堆栈,用 malloc 申请的内存),前者称为 file-backed pages,后者称为 anonymous pages。File-backed pages 在发生换页(page-in 或 page-out)时,是从它对应的文件读入或写出; anonymous pages 在发生换页时,是对交换区进行读 /写操作。

比较好文章链接:单纯说 /proc/meminfo 里的各项数据 http://linuxperf.com/?p=142

2.ps命令

常用的就是ps -ef和pf aux

ps -ef 是用标准的格式显示进程的。其格式如下:

UIDPIDPPIDCSTIMETTYCMD
用户ID进程的ID 父进程ID 进程占用CPU的百分比 进程启动的时间 

该进程在那个终端上运行。

若与终端无关,则显示? 

若为pts/0等,则表示由网络连接主机进程。 

命令的名称和参数

ps aux 是用BSD的格式来显示。其格式如下:

USERPID%CPU%MEMVSZRSSTTYSTATSTARTTIMECOMMAND
用户名同上进程占用的CPU百分比占用内存的百分比该进程使用的虚拟內存量(KB)

该进程占用的固定內存量(KB)

(驻留中页的数量) 

同上进程的状态同上该进程实际使用CPU运行的时间同上

其中STAT状态位常见的状态字符有
D      //无法中断的休眠状态(通常 IO 的进程);
R      //正在运行可中在队列中可过行的;
S      //处于休眠状态;
T      //停止或被追踪;
W      //进入内存交换 (从内核2.6开始无效);
X      //死掉的进程 (基本很少见);
Z      //僵尸进程;
<      //优先级高的进程
N      //优先级较低的进程
L      //有些页被锁进内存;
s      //进程的领导者(在它之下有子进程);
l      //多线程,克隆线程(使用 CLONE_THREAD, 类似 NPTL pthreads);
+      //位于后台的进程组;

3.free 命令显示系统内存的使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存。

$ free -h -s 3

上面的命令每隔 3 秒输出一次内存的使用情况,直到你按下 ctrl + c。

# free

Mem 行(第二行)是内存的使用情况。
Swap 行(第三行)是交换空间的使用情况。
total 列显示系统总的可用物理内存和交换空间大小。
used 列显示已经被使用的物理内存和交换空间。表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。
free 列显示还有多少物理内存和交换空间可用使用。
shared 列显示被共享使用的物理内存大小。
buff/cache 列显示被 buffer 和 cache 使用的物理内存大小。
available 列显示还可以被应用程序使用的物理内存大小。

used2:实际使用的buffers 与cache 总量,也是实际使用的内存总量。
free2:未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存

total = used + free
total = used2 + free2
used = buffers + cached + used2
free2 = buffers + cached + free

 

buff/cache

A buffer is something that has yet to be "written" to disk.

A cache is something that has been "read" from the disk and stored for later use.

先来提一个问题: buffer 和 cache 应该是两种类型的内存,但是 free 命令为什么会把它们放在一起呢?

buffer 在操作系统中指 buffer cache, 中文一般翻译为 "缓冲区"。要理解缓冲区,必须明确另外两个概念:"扇区" 和 "块"。扇区是设备的最小寻址单元,也叫 "硬扇区" 或 "设备块"。块是操作系统中文件系统的最小寻址单元,也叫 "文件块" 或 "I/O 块"。每个块包含一个或多个扇区,但大小不能超过一个页面,所以一个页可以容纳一个或多个内存中的块。当一个块被调入内存时,它要存储在一个缓冲区中。每个缓冲区与一个块对应,它相当于是磁盘块在内存中的表示(下图来自互联网):

注意,buffer cache 只有块的概念而没有文件的概念,它只是把磁盘上的块直接搬到内存中而不关心块中究竟存放的是什么格式的文件。

cache 在操作系统中指 page cache,中文一般翻译为 "页高速缓存"。页高速缓存是内核实现的磁盘缓存。它主要用来减少对磁盘的 I/O 操作。具体地讲,是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。页高速缓存缓存的是内存页面。缓存中的页来自对普通文件、块设备文件(这个指的就是 buffer cache 呀)和内存映射文件的读写
页高速缓存对普通文件的缓存我们可以这样理解:当内核要读一个文件(比如 /etc/hosts)时,它会先检查这个文件的数据是不是已经在页高速缓存中了。如果在,就放弃访问磁盘,直接从内存中读取。这个行为称为缓存命中。如果数据不在缓存中,就是未命中缓存,此时内核就要调度块 I/O 操作从磁盘去读取数据。然后内核将读来的数据放入页高速缓存中。这种缓存的目标是文件系统可以识别的文件(比如 /etc/hosts)。
页高速缓存对块设备文件的缓存就是我们在前面介绍的 buffer cahce。因为独立的磁盘块通过缓冲区也被存入了页高速缓存(缓冲区最终是由页高速缓存来承载的)。

到这里我们应该搞清楚了:无论是缓冲区还是页高速缓存,它们的实现方式都是一样的。缓冲区只不过是一种概念上比较特殊的页高速缓存罢了。
那么为什么 free 命令不直接称为 cache 而非要写成 buff/cache? 这是因为缓冲区和页高速缓存的实现并非天生就是统一的。在 linux 内核 2.4 中才将它们统一。更早的内核中有两个独立的磁盘缓存:页高速缓存和缓冲区高速缓存。前者缓存页面,后者缓存缓冲区。当你知道了这些故事之后,输出中列的名称可能已经不再重要了。

free 与 available

在 free 命令的输出中,有一个 free 列,同时还有一个 available 列。这二者到底有何区别?
free 是真正尚未被使用的物理内存数量。至于 available 就比较有意思了,它是从应用程序的角度看到的可用内存数量。

Linux 内核为了提升磁盘操作的性能,会消耗一部分内存去缓存磁盘数据,就是我们介绍的 buffer 和 cache。所以对于内核来说,buffer 和 cache 都属于已经被使用的内存。当应用程序需要内存时,如果没有足够的 free 内存可以用,内核就会从 buffer 和 cache 中回收内存来满足应用程序的请求。所以从应用程序的角度来说,available  = free + buffer + cache。请注意,这只是一个很理想的计算方式,实际中的数据往往有较大的误差。

交换空间(swap space)

swap space 是磁盘上的一块区域,可以是一个分区,也可以是一个文件。所以具体的实现可以是 swap 分区也可以是 swap 文件。当系统物理内存吃紧时,Linux 会将内存中不常访问的数据保存到 swap 上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问 swap 上存储的内容时,再将 swap 上的数据加载到内存中,这就是常说的换出和换入。交换空间可以在一定程度上缓解内存不足的情况,但是它需要读写磁盘数据,所以性能不是很高。

现在的机器一般都不太缺内存,如果系统默认还是使用了 swap 是不是会拖累系统的性能?理论上是的,但实际上可能性并不是很大。并且内核提供了一个叫做 swappiness 的参数,用于配置需要将内存中不常用的数据移到 swap 中去的紧迫程度。这个参数的取值范围是 0~100,0 告诉内核尽可能的不要将内存数据移到 swap 中,也即只有在迫不得已的情况下才这么做,而 100 告诉内核只要有可能,尽量的将内存中不常访问的数据移到 swap 中。在 ubuntu 系统中,swappiness 的默认值是 60。如果我们觉着内存充足,可以在 /etc/sysctl.conf 文件中设置 swappiness:

vm.swappiness=10

如果系统的内存不足,则需要根据物理内存的大小来设置交换空间的大小。

4.Linux中常用内存分配函数的异同点

用户/内核API名称物理连续?大小限制单位场景
用户空间malloc/calloc/realloc/free 不保证 堆申请 字节calloc初始化为0;realloc改变内存大小。
alloca  栈申请 字节向栈申请内存
mmap/munmap   将文件利用虚拟内存技术映射到内存中去。
brk、sbrk    虚拟内存到内存的映射。sbrk(0)返回program break地址,sbrk调整对的大小。

间    

 vmalloc/vfree

虚拟连续

物理不定

 vmalloc区大小限制

 页

VMALLOC区域

可能睡眠,不能从中断上下文中调用,或其他不允许阻塞情况下调用。

VMALLOC区域vmalloc_start~vmalloc_end之间,vmalloc比kmalloc慢,适用于分配大内存。

  slabkmalloc/kcalloc/krealloc/kfree物理连续

64B-4MB

(随slab而变)

 2^order字节

Normal区域

大小有限,不如vmalloc/malloc大。

最大/小值由KMALLOC_MIN_SIZE/KMALLOC_SHIFT_MAX,对应64B/4MB。

从/proc/slabinfo中的kmalloc-xxxx中分配,建立在kmem_cache_create基础之上。

kmem_cache_create物理连续64B-4MB

字节大小,需对齐

Normal区域

便于固定大小数据的频繁分配和释放,分配时从缓存池中获取地址,释放时也不一定真正释放内存。通过slab进行管理。

伙伴系统 __get_free_page/__get_free_pages物理连续 4MB(1024页)

Normal区域

 __get_free_pages基于alloc_pages,但是限定不能使用HIGHMEM。
 alloc_page/alloc_pages/free_pages物理连续4MB 

Normal/Vmalloc都可 

 CONFIG_FORCE_MAX_ZONEORDER定义了最大页面数2^11,一次能分配到的最大页面数是1024。

5.procrank命令

procrank是android system/xbin工具,能够列出各进程占用内存情况,从大到小排列

  1. root@msm8952_64:/ # procrank
  2. PID Vss Rss Pss Uss cmdline
  3. 1628 2275600K 116260K 64803K 56572K system_server
  4. 4740 1562536K 106804K 54520K 45168K com.android.systemui
  5. 5325 1570524K 91976K 40356K 30108K com.android.launcher3

一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

Vss与PS的VSIZE相同是单个进程全部可访问的地址空间,其大小包括可能还尚未在内存中驻留的部分。比如地址空间已经被 malloc 分配,但是还没有实际写入。对于确定单个进程实际内存使用大小, VSS 用处不大

RSS  是单个进程实际占用的内存大小。RSS 易被误导的原因在于, 它包括了该进程所使用的所有共享库的全部内存大小。对于单个共享库, 尽管无论多少个进程使用,实际该共享库只会被装入内存一次。对于单个进程的内存使用大小, RSS  不是一个精确的描述。

PSS 不同于RSS,它只是按比例包含其所使用的共享库大小。例如, 三个进程使用同一个占用 30 内存页的共享库。 对于三个进程中的任何一个,PSS 将只包括 10 个内存页。PSS 是一个非常有用的数字,因为系统中全部进程以整体的方式被统计, 对于系统中的整体内存使用是一个很好的描述。如果一个进程被终止, 其PSS 中所使用的共享库大小将会重新按比例分配给剩下的仍在运行并且仍在使用该共享库的进程。此种计算方式有轻微的误差,因为当某个进程中止的时候, PSS 没有精确的表示被返还给整个系统的内存大小。

USS 是单个进程的全部私有内存大小。亦即全部被该进程独占的内存大小。USS 是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。

VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)

6.top命令

VIRT:virtual memory usage 虚拟内存
1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等
2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量

RES:resident memory usage 常驻内存
1、进程当前使用的内存大小,但不包括swap out
2、包含其他进程的共享
3、如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反
4、关于库占用内存的情况,它只统计加载的库文件所占内存大小

SHR:shared memory 共享内存
1、除了自身进程的共享内存,也包括其他进程的共享内存
2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小
3、计算某个进程所占的物理内存大小公式:RES – SHR
4、swap out后,它将会降下来

DATA
1、数据占用的内存。如果top没有显示,按f键可以显示出来。
2、真正的该程序要求的数据空间,是真正在运行中要使用的。

文章知识点与官方知识档案匹配,可进一步学习相关知识
CS入门技能树Linux入门初识Linux40395 人正在系统学习中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/709359.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习中的正则化技术——Python实现

在机器学习中,我们非常关心模型的预测能力,即模型在新数据上的表现,而不希望过拟合现象的的发生,我们通常使用正则化(regularization)技术来防止过拟合情况。正则化是机器学习中通过显式的控制模型复杂度来避免模型过拟合、确保泛化能力的一种有效方式。如果将模型原始的…

ConfigurationClassPostProcessor类,@Configuration注解的底层实现

概览 由前文可知,ConfigurationClassPostProcessor是作为Spring中的内置类被添加到容器中,【源码学习】Spring启动流程ConfigurationClassPostProcessor不仅实现了BeanFactoryPostProcessor(BFPP)并且实现了BeanDefinitionRegistryPostProcessor,具有比一般BFPP更高的初始…

随机二次元图片API第三弹

本来我都把第二弹置顶上来了,没打算在发第三弹的,然后想着想着又憋出来这么多话,想想不发不就白浪费我那么多脑细胞了。Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 随机二次元图…

记一次解决OTA死机重启bug,如何分析与解决措施?!

背景: 平台:stm32mp151平台 什么是OTA? 说起OTA我们应该都不陌生,它是一种可以为设备无损失升级系统的方式,能将新功能远程部署到产品上。 我们不仅可以通过网络下载OTA升级包,也可以通过下载OTA升级包到SD卡或U盘后再对设备升级。 OTA下载方式:短信方式 PUSH方式 网络定…

插件助手

Fitten Codevscode安装插件先注册登录智能补全问答生成代码选择代码,编辑代码Github Copilot Kite TabNine

Google Cloud Next ’24 Recap 开启 AI 新篇章,Cloud Ace 独立解决方案助力企业降本增效

北京时间 2024年4月26日,Cloud Ace 云一 受邀参与 Google Cloud Next’24 Recap 在深圳的线下活动,并设置展位。本次活动主要聚焦于 Next’24(Las Vegas)成果展示,给中国客户和开发者深入解读 Google Cloud Next ’24 大会上 Gemini、Vertex AI、BigQuery 等产品服务的重要…

感谢西部数码大佬寄的国庆礼物

事情是这样的Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 感谢西部数码大佬寄的国庆礼物 日期:2019-10-18 阿珏 谈天说地 浏览:1499次 评论:6条事情是这样的然后就这样最后就得…

借助表单拖拽设计器的优势实现流程化办公!

想要了解低代码技术平台、表单拖拽设计器的优势特点以及应用价值的客户朋友,可以在本文中探寻更多有价值的资讯。实现流程化办公,可以让企业提质、降本、增效,从而得到更多市场份额,提升市场竞争力,收获更多发展机遇。低代码技术平台在各中小企业中得到了广泛的地运用和推…

三周年活动解密游戏

首先先感谢来访和参与的小伙伴们,让 三周年活动完美结束,寄出N+1份福袋。三周年活动总共提供了两种福袋获取方式,第一种则就留了个诡异的链接...... 当你点进去的那一刻起游戏就开始了 Link start!Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此…

我喜欢二次元

我喜欢二次元,因为我喜欢那个世界Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 我喜欢二次元 日期:2019-5-20 阿珏 二次元 浏览:7250次 评论:15条我喜欢二次元,是因为我喜欢那…