Mod*_*ire 5 unix linux memory aix sbrk
我在各种操作系统中存在内存管理问题.
我的程序是一个服务器,它执行一些可能需要几GB内存的处理.之后,它会在等待几个小时直到另一个请求到达时释放大部分内存.
在AIX和Solaris上,我观察到以下行为,
当我释放内存时,内存不会返回给操作系统.进程使用的虚拟内存量总是增加 - 永不减少.对于物理内存也是如此,直到它的极限.因此,我们似乎也在睡眠模式下使用所有这些内存.
什么时候这个内存可以返回给操作系统?我该怎么做?
Linux是不同的:它似乎有时会返回内存,但我无法理解何时以及如何.例如,我有一个场景,其中请求之前的过程是100MB,然后是高峰时的700MB,并且在释放所有下降到600MB之后.我不明白 - 如果Linux为操作系统提供内存,为什么不是全部?
glibc库(通常用作Linux中的标准C库)可以通过两种方式分配内存 - 使用sbrk()或使用mmap().它将使用mmap()进行足够大的分配.
用sbrk()分配的内存不能轻易再次放弃(仅在特殊情况下,据我所知glibc甚至不尝试).可以使用munmap()返回使用mmap()分配的内存.
如果您依赖于能够将内存返回到操作系统,则可以直接使用mmap()而不是malloc(); 但如果你分配了很多小块,这将变得效率低下.您可能需要在mmap()之上实现自己的池分配器.
大多数情况下,直到进程终止,内存才会返回给系统。根据操作系统和运行时库,内存可能会返还给系统,但我不知道有任何可靠的方法来确保这会发生。
如果处理需要几 GB 内存,让您的服务器等待请求,然后生成一个新进程来处理数据 - 您可以使用管道与您的服务器进行通信。处理完成后,返回结果并终止生成的进程。
我认为内存分配的方式(并且可能返回给操作系统)是在 libc 中。您正在使用的编程语言/库堆栈可能是造成这种情况的原因。
我假设 glibc 将在堆顶部返回非碎片内存。您的进程可能会分配 10MB 的数据,它将一直使用。之后,将分配用于处理的 500MB 数据。之后,分配即使在处理后仍保留的一小部分数据(可能是处理的结果)。之后又分配了 500MB 内存布局是:
|已使用 10MB|500MB 处理|1MB 结果|500MB 处理| = 总计 1011 MB
当释放1000MB时,内存布局为
|已用 10MB|已释放 500MB|结果 1MB|已释放 500MB| glibc 现在可能会在最后返回内存... |已使用 10MB|已释放 500MB|结果为 1MB| = 511 MB“正在使用”,也仅使用了其中的 11MB。
我认为这就是发生的情况,您需要进行进一步的研究(想到单独的内存池)以确保所有内存都将被释放