9

I have an issue with memory management in various operating systems.

My program is a server that does some processing that could take a few GB of memory. After that, it releases most of the memory while it waits for a few hours until another request arrives.

On AIX and Solaris, I observe the following behavior,

When I free memory, the memory is not returned back to the operating system. The amount of virtual memory used by a process always increases - never decreases. The same is true for the physical memory, up to its limit. Thus it appears that we use all this memory in sleep mode as well.

When this memory can be returned back to OS? How can I make it?

Linux is different: it appears that is does return memory sometimes, but I'm not able to understand when and how. I have for example a scenario in which the process before a request was 100MB, then 700MB at the peak, and after releasing all that it was down to 600MB. I don't understand it - if Linux gives back memory to the OS, why not all of it?

4

5 回答 5

13

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

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

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

于 2012-08-21T08:56:57.527 回答
5

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

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

于 2012-08-21T08:57:11.473 回答
2

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

我假设 glibc 将在堆顶部返回非碎片内存。您的进程可能会分配 10MB 的数据,它将一直使用。之后,将分配 500MB 用于处理的数据。之后,即使在处理(可能是处理的结果)之后仍保留的一小部分数据被分配。之后再分配 500MB 内存布局为:

|10MB 已用|500 MB 处理|1MB 结果|500MB 处理| = 总计 1011 MB

当 1000MB 被释放时,内存布局为

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

我认为这就是发生的情况,您需要做进一步的研究(想到单独的内存池)以确保所有内存都将被释放

于 2012-08-21T08:28:10.823 回答
0

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

于 2013-02-06T10:12:54.827 回答
0

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

不幸的是,您在生成此进程和进程间通信方面效率低下(我注意到您正在进行大量处理 - 我不知道这是否意味着您的进程间通信具有相当大的数据需求)。但是,您将获得所需的内存行为。请注意,操作系统不应复制实际 JVM 消耗的内存,前提是您生成了相同的JVM 二进制映像。

于 2012-08-21T08:32:09.230 回答