嵌入式Linux:内存碎片
在许多嵌入式系统中,内存碎片是一个令人担忧的问题。特别是对于运行较长时间(数月、数年等)的软件。对于许多项目来说,解决方案就是不使用动态内存分配,例如 malloc/free 和 new/delete。尽可能使用全局内存,并且频繁分配和释放的类型的内存池是避免动态内存管理使用的好策略。
在嵌入式 Linux 中如何解决这个问题?我看到很多库都使用动态内存。操作系统是否有防止内存碎片的机制?它会定期清理堆吗?或者应该避免在嵌入式环境中使用这些库?
In many embedded systems, memory fragmentation is a concern. Particularly, for software that runs for long periods of time (months, years, etc...). For many projects, the solution is to simply not use dynamic memory allocation such as malloc/free and new/delete. Global memory is used whenever possible and memory pools for types that are frequently allocated and deallocated are good strategies to avoid dynamic memory management use.
In Embedded Linux how is this addressed? I see many libraries use dynamic memory. Is there mechanism that the OS uses to prevent memory fragmentation? Does it clean up the heap periodically? Or should one avoid using these libraries in an embedded environment?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不存在能够避免至少 log(M/m) 因子的碎片的非移动内存分配器,其中 M = 最大对象请求的大小,m = 最小对象请求的大小(这是一个经典结果,因为罗布森,1971)。
我与从事实时系统编程的人(包括在空中客车公司)一起工作,他们刻意避免使用动态内存分配,而是使用池,正如您提到的。
然而,操作系统和内存分配之间存在很大差异。向程序员公开的动态内存分配是库的一部分,与操作系统关系不大(除了作为内存源)。 Linux 本身使用基于slab 的内存分配器来实现其内部目的;我认为嵌入式 Linux 也会做同样的事情,但我不确定。
There is no non-moving memory allocator that can avoid fragmentation of at least a log(M/m) factor, where M = the size of the largest object request, and m = the size of the smallest (this is a classic result due to Robson, 1971).
I work with folks who do real-time systems programming (including at Airbus), and they studiously avoid the use of dynamic memory allocation, instead using pools, as you mention.
There is, however, a big difference between an OS and memory allocation. Dynamic memory allocation, as exposed to the programmer, is part of the library and has little to do with the OS (except as a source of memory). Linux itself uses a slab-based memory allocator for its own internal purposes; I assume Embedded Linux does the same, but am not sure.
这取决于你如何使用内存。
Linux 在大多数情况下使用虚拟内存,其中应用程序将内存视为连续的内存块。底层内核完成了虚拟内存和物理内存之间的所有手动映射,这样您就不必处理它。
从物理上讲,您的内存可能分散在各处,但您的应用程序看不到这一点。
现在,如果您确实想要连续的物理内存怎么办?当您想要执行 DMA 或硬件的一些其他硬要求时,通常会发生这种情况。在这种情况下,您可以分配指向特定物理内存的内存页。但你必须将其视为例外而不是常态。
我以这样的方式设计我的系统:大多数驱动程序(“实时”驱动程序除外)都位于用户空间。这样你就可以获得用户空间的所有好处(更多的库、语言),如果有错误,不要杀死内核,并利用可用的虚拟内存。
That depends on how you use the memory.
Linux uses virtual memory for most cases, in which the application see the memory as a contiguous block of memory. The underlying kernel does all the manual mapping between the virtual memory and the physical memory, so that you don't have to deal with it.
Physically, your memory might scatter around, but your applications don't see that.
Now, what if you really want contiguous physical memory? This often happen when you want to perform DMA, or some other hard requirements from your hardware. On that case, you are allowed to allocate memory page that points to specific physical memory. But you have to make this as an exception other than norm.
I designed my system in such a way that most driver (except "real-time" driver) on to the user space. That way you get all the benefits of the user space (more libraries, languages), don't kill the kernel if you have a bug, and utilizes the virtual memory available.
恕我直言,无论哪种情况,您都可以搜索内存分配算法,这会导致更少的碎片。并且,在测量内存需求后配置此算法或内存分配实现。
我可以推荐 TLSF 作为开始。
IMHO, in either case, you may search for memory allocation algorithms, which cause less fragmentation. And, configure this algorithm or your memory allocation implementation after measuring your memory requirements.
I can recommend TLSF as a start.