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