嵌入式Linux内存使用与性能优化

简介:

2000元阿里云代金券免费领取,2核4G云服务器仅664元/3年,新老用户都有优惠,立即抢购>>>


阿里云采购季(云主机223元/3年)活动入口:请点击进入>>>,


阿里云学生服务器(9.5元/月)购买入口:请点击进入>>>,


1.  怎样查看系统当前可用内存 ?

答:使用 free 命令即可。如下图所示:

 

说明:


buffers: 主要用来给Linux系统中块设备做缓冲区(把分散的写操作集中进行,减少对磁盘或者Flash设备的写次数,提高系统性能)

cached:用来缓冲打开的文件(把从磁盘或者Flash中读取的数据保存在内存中,若再次读取该块时,则直接从内存中读取而不需要再访问磁盘或者Flash设备)

在系统中内存是很宝贵的资源,故Linux在内存使用上的宗旨是:如果内存充足,不用白不用,尽量使用内存来缓存一些文件,从而加快进程的运行速度;而当内存不足的时候,这些内存又会被回收,供程序使用。

所以,当前系统真正空闲可以使用的内存为:free+buffers+cached (KB)

 

2.  free命令得到的数据是哪里来的?

 

答: 来自 /proc 虚拟文件系统,我们可以通过 /proc/meminfo文件来了解当前系统的内存使用情况,如下图所示:



从上面可以看出,系统一共有 2050600KB的物理内存,当前系统可用的物理内存为: Memfree+Buffers+Cached

 

3.  操作系统的虚拟内存与物理内存机制

 

操作系统为程序员屏蔽了物理内存的使用,在32位操作系统中,每个进程面对的都是4GB的内存空间,称为虚拟内存。操作系统采用了延迟分配物理内存的策略,针对进程的内存分配请求,它只是在内核中分配了一段虚拟地址,只有当确实使用这块内存时,系统才会为其分配物理地址。

 

我们来看一下下面这段代码: 

 

#include <stdio.h> #include <stdlib.h> #include <string.h>  int main() {     char * p = (char *)malloc(10);      char * q = (char *)malloc(200);      strcpy(p,"123");      return 0;  }

问题一:该代码执行时,内存的分配过程是怎样的?

 

(1)  char * p= (char *)malloc(10);

 

   char *q =  (char *)malloc(200);

 

这2句,系统只给该进程分配了虚拟内存,而并没有分配物理内存。

 

(2)  strcpy(p,"123");

 

这一句,由于进程需要真正使用这块内存了,因此系统会产生一个页故障,从而为该进程分配一个物理页面。

 

(3)  整个程序最终只是为 p 分配的物理内存,而只是给 q 分配了虚拟内存。

 

问题二: 该代码实际分配的内存究竟多大?

 

系统给该进程分配的虚拟内存为 : 10B + 200B = 210 Byte

 

给该进程分配的物理内存为 4KB,因为系统规定,分配物理内存的最小单位为一个物理页面,一般是4KB

 

注:用户态申请内存是以Byte为单位,而内核态申请内存是以页面(4KB)为单位

 

4.  Linux的内存回收机制

 

在Linux系统中,有一个专门的守护进程 kswapd,它会定期地检查系统中空闲内存的数量,一旦发现空闲内存数量小于一个阈值的时候,就会将若干页面换出,存放到交换分区中,以腾出足够的内存空间。

 

对于交换分区的使用,有着如下的规则:

 

对于那些没有被改写过的页面,这块内存不需要写到交换分区上,可以直接回收。


对于那些已经改写的页面,我们称之为脏页面(dirty page),则需要写到交换分区。

 

但在使用Flash作为存储介质的嵌入式设备中,一般没有交换分区,因此对于dirty page,只能保留在系统中,无法换出。原因如下:

 

(1) 一旦使用了交换分区,系统的性能会下降很快,不可接受

 

(2) Flash的写次数是有限的,大概在几十万次,如果在Flash上面建立交换分区的话,必然导致对Flash的频繁读写,进而影响Flash的寿命。


下面分析下,一个进程中,哪些内存可能是 dirty page 页面,哪些不是?


(1) 代码段,其权限是只读属性,不可能被改写,所以其所占的物理内存,都不是 dirty page

 

(2) 数据段,其权限是可读、可写,所以其所占的物理内存可能是 dirty page,也可能不是

 

(3) 堆栈段,其没有对应的映射文件,内容都是通过程序来改写的,所以其所占的物理内存全部是 dirty page

 

(4) 共享内存,其所占的物理内存,全部是 dirty page


综上所述,也就是说, 可以直接被回收的内存,主要是进程的代码段和未修改的数据段。

 

5.  为什么在 malloc时,要求输入申请的空间大小,而在 free 时,不需要输入释放的空间大小?

 

    因为程序调用 malloc 函数申请内存时,并不是直接向操作系统申请,而是先由 glibc 的内存管器模块接收请求,它再通过系统调用向内核申请一块内存并将地址p返回给用户,同时,在 p-4 这个地址记录下 malloc 空间的大小,glibc 在 free 这块内存的时候,通过 p-4 即可知道需要释放的内存大小是多少。




本文转自 Jhuster 51CTO博客,原文链接:http://blog.51cto.com/ticktick/817545,如需转载请自行联系原作者

相关文章
|
12天前
|
算法 安全 Linux
探索Linux内核的虚拟内存管理
【5月更文挑战第20天】 在本文中,我们将深入探讨Linux操作系统的核心组成部分之一——虚拟内存管理。通过剖析其关键组件和运作机制,揭示虚拟内存如何提供高效的内存抽象,支持庞大的地址空间,以及实现内存保护和共享。文章将重点讨论分页机制、虚拟内存区域(VMAs)的管理、页面置换算法,并简要分析这些技术是如何支撑起现代操作系统复杂而多变的内存需求的。
|
17天前
|
消息中间件 算法 Linux
【Linux】详解如何利用共享内存实现进程间通信
【Linux】详解如何利用共享内存实现进程间通信
|
3天前
|
缓存 算法 安全
探索Linux内核的虚拟内存管理
【5月更文挑战第29天】 在现代操作系统中,虚拟内存是支持多任务处理和内存保护的关键组件。本文深入分析了Linux操作系统中的虚拟内存管理机制,包括其地址空间布局、分页系统以及内存分配策略。我们将探讨虚拟内存如何允许多个进程独立地访问它们自己的地址空间,同时由操作系统管理物理内存资源。此外,文章还将涉及虚拟内存所带来的性能影响及其优化方法。
|
8天前
|
存储 缓存 程序员
C++内存管理:避免内存泄漏与性能优化的策略
C++内存管理涉及程序稳定性、可靠性和性能。理解堆和栈的区别至关重要,其中堆内存需手动分配和释放。避免内存泄漏的策略包括及时释放内存、使用智能指针和避免野指针。性能优化策略则包括减少内存分配、选用合适数据结构、避免深拷贝及缓存常用数据。通过这些最佳实践,可提升C++程序的效率和质量。
|
10天前
|
消息中间件 存储 安全
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(下)
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(下)
|
10天前
|
消息中间件 算法 Linux
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(上)
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(上)
|
14天前
|
算法 Java Python
【Python 的内存管理机制专栏】Python 内存管理实战:性能优化与内存泄漏检测
【5月更文挑战第18天】Python内存管理关乎程序性能与稳定性。优化包括避免过多临时对象,如优化列表推导式减少对象创建。警惕循环引用造成的内存泄漏,如示例中的Node类。使用`gc`模块检测泄漏,通过`gc.set_debug(gc.DEBUG_LEAK)`和`gc.collect()`获取信息。实践中需持续分析内存使用,优化算法、数据结构和资源释放,以提升程序质量与效率。
【Python 的内存管理机制专栏】Python 内存管理实战:性能优化与内存泄漏检测
|
17天前
|
存储 Linux 程序员
【操作系统原理】—— Linux内存管理
【操作系统原理】—— Linux内存管理
|
17天前
|
Java Linux Arthas
linux上如何排查JVM内存过高?
linux上如何排查JVM内存过高?
831 0
http://www.vxiaotou.com