【问题标题】:linux new/delete, malloc/free large memory blockslinux new/delete, malloc/free 大内存块
【发布时间】:2011-02-02 04:20:12
【问题描述】:

我们有一个运行多个 CORBA 服务器进程的 linux 系统 (kubuntu 7.10)。 服务器软件使用 glibc 库进行内存分配。 linux PC有4G物理内存。出于速度原因,已禁用交换。

在收到处理数据的请求后,其中一个服务器进程会分配一个大数据缓冲区(使用标准 C++ 运算符“new”)。缓冲区大小取决于许多参数,但通常约为 1.2G 字节。它可以达到大约 1.9G 字节。请求完成后,使用“删除”释放缓冲区。

这适用于分配相同大小的缓冲区的多个连续请求,或者如果请求分配的大小比前一个更小。 内存似乎是空闲的 - 否则缓冲区分配尝试最终会在几个请求后失败。 在任何情况下,我们都可以看到使用 KSysGuard 等工具为每个请求分配和释放的缓冲内存。

当请求需要比前一个更大的缓冲区时,就会出现问题。 在这种情况下,operator 'new' 会引发异常。 就好像从第一次分配中释放的内存无法重新分配,即使有足够的可用物理内存。

如果我在第一次操作后杀死并重新启动服务器进程,那么第二次请求更大的缓冲区大小会成功。即终止进程似乎将释放的内存完全释放回系统。

谁能解释一下这里可能发生了什么? 可能是某种碎片或映射表大小问题吗? 我正在考虑用 malloc/free 替换 new/delete,并使用 mallopt 调整内存释放到系统的方式。

顺便说一句 - 我不确定它是否与我们的问题有关,但服务器使用在每个处理请求时创建和销毁的 Pthreads。

【问题讨论】:

    标签: linux memory malloc new-operator free


    【解决方案1】:

    如果这是一台 32 位机器,您将拥有 3Gb 的地址空间供您使用 - 1Gb 是为内核保留的。除此之外,共享库、exe 文件将占用相当多的地址空间,数据段等。您应该查看/proc/pid/maps 以了解地址空间的布局方式。

    很难说有多少物理地址空间可用,所有系统进程、内核和您的其他进程都会占用它。假设这些总和不超过 1Gb,您仍然可以使用 3Gb。

    可能发生的是碎片化:

    0Gb 3Gb ----------------------------------------------------------------- -------- |东西 |堆,1.2Gb 分配的东西 |空闲堆 |堆栈| ----------------------------------------------------------------- --------

    然后你释放了大对象,但在其他一些内存之间 分配,留给你这个:

    0Gb 3Gb ----------------------------------------------------------------- -------------- |东西 |堆,1.2Gb 空闲 |小对象 |空闲堆 |堆栈| ----------------------------------------------------------------- --------------

    如果您现在尝试分配一个更大的对象,它会不适合可用的 1.2Gb 空间 并且可能也不适合free heap 空间,因为它可能没有足够的空间。

    如果您大量使用堆栈,则可能是堆栈增长和占用空间 否则可用于堆空间 - 尽管默认情况下大多数发行版将堆栈限制为 8-10Mb。

    使用 malloc/realloc 无济于事。然而,如果你知道你需要的最大对象的大小,你可以在启动时保留那么多。那一块永远不应该被释放/删除,它应该被重复使用。不过,这是否会让您在其他地方陷入其他麻烦很难说 - 可供其他对象使用的空间会变小。

    【讨论】:

      【解决方案2】:

      非常感谢您的回复。 进一步的调查表明,碎片确实是问题所在。 在第一个请求到达时保留我们将需要的最大缓冲区并为后续请求保留该缓冲区似乎是可行的。

      【讨论】:

        【解决方案3】:

        你的地址空间用完了,所以没有足够大的块来满足你的分配。

        解决办法是运行 64 位操作系统——毕竟现在是 21 世纪!

        当然,您需要重新测试应用程序的 64 位兼容性(并重新编译等),但从长远来看这是有意义的。如今,4G 对于服务器来说并不是很多内存;一个相当适中的有 16-32G。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-17
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多