【问题标题】:Embedded Linux: Memory Fragmentation嵌入式 Linux:内存碎片
【发布时间】:2011-06-10 12:13:41
【问题描述】:

在许多嵌入式系统中,内存碎片是一个问题。特别是对于长时间运行(数月、数年等)的软件。对于许多项目,解决方案是简单地不使用动态内存分配,例如 malloc/free 和 new/delete。尽可能使用全局内存,而频繁分配和释放类型的内存池是避免使用动态内存管理的好策略。

在嵌入式 Linux 中,这是如何解决的?我看到许多库使用动态内存。操作系统是否有防止内存碎片的机制?它会定期清理堆吗?还是应该避免在嵌入式环境中使用这些库?

【问题讨论】:

    标签: memory-management embedded-linux fragmentation


    【解决方案1】:

    没有非移动内存分配器可以避免至少一个 log(M/m) 因子的碎片,其中 M = 最大对象请求的大小,m = 最小对象的大小(这是一个Robson 的经典结果,1971)。

    我与从事实时系统编程的人一起工作(包括在空中客车公司),他们刻意避免使用动态内存分配,而是使用池,正如你提到的那样。

    但是,操作系统和内存分配之间存在很大差异。向程序员公开的动态内存分配是库的一部分,与操作系统几乎没有关系(作为内存来源除外)。 Linux 本身使用基于slab 的内存分配器用于其内部用途;我认为嵌入式 Linux 也是如此,但不确定。

    【讨论】:

    • 空客的那些家伙遇到使用动态内存的库时会怎么做?
    • AFAIK,这种情况永远不会出现。
    【解决方案2】:

    这取决于你如何使用内存。

    Linux 在大多数情况下使用虚拟内存,其中应用程序将内存视为连续的内存块。底层内核完成了虚拟内存和物理内存之间的所有手动映射,因此您不必处理它。 从物理上讲,您的内存可能会四处散落,但您的应用程序看不到这一点。

    现在,如果您真的想要连续的物理内存怎么办?当您想要执行 DMA 或硬件的其他一些硬要求时,通常会发生这种情况。在这种情况下,您可以分配指向特定物理内存的内存页面。但是你必须把它作为一个例外而不是规范。

    我设计我的系统的方式是让大多数驱动程序(“实时”驱动程序除外)进入用户空间。这样你就可以获得用户空间的所有好处(更多的库、语言),如果你有一个错误就不会杀死内核,并利用可用的虚拟内存。

    【讨论】:

    • 您能否提供更多关于如何“分配指向特定物理内存的内存页”的信息?
    • “我设计我的系统的方式是让大多数驱动程序(“实时”驱动程序除外)进入用户空间。”听起来像是一个错字。什么意思?
    • Daryl,使用 /dev/mem 从用户空间访问物理地址。
    • 实时驱动程序通常对延迟敏感,需要内核持续关注。只有在这种情况下,我才会将驱动程序移至内核空间。
    【解决方案3】:

    恕我直言,无论哪种情况,您都可以搜索内存分配算法,从而减少碎片。并且,在测量您的内存需求后配置此算法或您的内存分配实现。

    我可以推荐TLSF 作为开始。

    【讨论】:

      猜你喜欢
      • 2014-04-09
      • 2013-08-14
      • 1970-01-01
      • 2010-10-26
      • 1970-01-01
      • 2014-07-14
      • 2018-09-25
      • 2012-12-11
      • 2011-01-17
      相关资源
      最近更新 更多