如何从进程返回内存到操作系统

我在各种操作系统中遇到内存pipe理问题。

我的程序是一个服务器,做一些处理,可能需要几GB的内存。 之后,它释放大部分内存,等待几个小时直到另一个请求到达。

在AIX和Solaris上,我观察到以下行为,

当我释放内存时,内存不会返回到操作系统。 进程使用的虚拟内存量总是增加 – 永远不会减less。 物理内存也是如此,达到极限。 因此,看起来我们在睡眠模式下也使用了所有这些内存。

当这个内存可以返回到操作系统? 我怎样才能做到这一点?

Linux是不一样的:看起来有时会返回内存,但是我无法理解何时以及如何。 举例来说,一个请求前的进程是100MB,最高700MB,释放到600MB之后。 我不明白 – 如果Linux给操作系统留下内存,为什么不把它全部?

Solutions Collecting From Web of "如何从进程返回内存到操作系统"

glibc库(通常用作Linux中的标准C库)可以使用sbrk()或mmap()两种方式分配内存。 它将使用mmap()分配足够大的分配。

用sbrk()分配的内存不能轻易放弃(只有在特殊情况下,据我所知glibc甚至不尝试)。 分配了mmap()的内存可以使用munmap()返回。

如果你依赖于能够返回内存到操作系统,你可以直接使用mmap()而不是malloc(); 但是如果你分配很多小块,这将变得效率低下。 您可能需要在mmap()之上实现您自己的池分配器。

大多数情况下,内存不会返回到系统,直到进程终止。 根据操作系统和运行时库,内存可能会回馈给系统,但是我不知道有什么可靠的方法来确保这种情况发生。

如果处理需要几GB的内存,让你的服务器等待请求,然后产生一个新的进程来处理数据 – 你可以使用管道与你的服务器进行通信。 处理完成后,返回结果并终止产生的进程。

内存分配的方式(也许给回到操作系统)是在libc中,我假设。 您正在使用的编程语言/库堆栈可能是这个原因。

我假设glibc会在堆的顶部返回非零碎的内存。 你的进程可能会分配10MB的数据,它将一直使用。 之后,将分配处理中使用的500MB数据。 之后,即使在处理之后也可以保留一小段数据(可能是处理的结果)。 之后又分配了500MB内存布局是:

|使用10MB | 500 MB处理| 1MB结果| 500MB处理| 总共1011MB

当释放1000MB时,内存布局是

| 10MB使用| 500MB释放| 1MB结果| 500MB释放| glibc现在可能会在最后返回内存… |已使用10MB |已释放500MB | 1MB结果| = 511 MB“使用中”也只有11MB的使用。

我认为会发生什么事情,你需要做进一步的研究(记住单独的内存池),以确保所有的内存将被释放

我认为唯一可靠可移植的方法是产生一个新的流程来处理您的请求。 一旦进程退出,操作系统将收获所有相关的内存。

不幸的是,这样会产生与产生这个过程和进程间通信相关的低效率(我注意到你正在做很多处理 – 我不知道这是否意味着你的进程间通信有相当大的数据需求)。 但是,你会得到你需要的记忆行为。 请注意,操作系统不应该复制实际JVM消耗的内存,前提是生成相同的 JVM二进制映像。

你应该看看分页是如何工作的。 如果它小于getpagesize(),则不能返回内存。