我们有一个运行许多 CORBA 服务器进程的 linux 系统(kubuntu 7.10)。服务器软件使用 glibc 库进行内存分配。linux PC有4G物理内存。出于速度原因,交换被禁用。
在接收到处理数据的请求后,其中一个服务器进程分配一个大数据缓冲区(使用标准 C++ 运算符“new”)。缓冲区大小取决于许多参数,但通常约为 1.2G 字节。它可以达到大约 1.9G 字节。请求完成后,使用“删除”释放缓冲区。
这适用于分配相同大小的缓冲区的多个连续请求,或者如果请求分配的大小比前一个小。内存似乎是空闲的 - 否则缓冲区分配尝试最终会在几个请求后失败。在任何情况下,我们都可以看到使用 KSysGuard 等工具为每个请求分配和释放缓冲区内存。
当请求需要比前一个更大的缓冲区时,就会出现问题。在这种情况下,operator 'new' 会引发异常。就好像从第一次分配中释放的内存无法重新分配,即使有足够的可用物理内存。
如果我在第一次操作后终止并重新启动服务器进程,则第二次请求更大的缓冲区大小会成功。即终止进程似乎将释放的内存完全释放回系统。
任何人都可以解释这里可能发生的事情吗?可能是某种碎片或映射表大小问题吗?我正在考虑用 malloc/free 替换 new/delete 并使用 mallopt 来调整内存释放到系统的方式。
顺便说一句 - 我不确定它是否与我们的问题有关,但服务器使用在每个处理请求上创建和销毁的 Pthreads。