0

我在 Solaris sparc 服务器上编写了一个测试程序并使用 Sun Studio 编译它

#include <iostream>

using namespace std;

int main()
{
    const int size =  9999;
    char *ptr[size];

    while(1)
    {
       for(int i = 0; i < size; i++)
       {
           ptr[i] = new char[2048];
       }
        for(int i = 0; i < size; i++)
        {
           delete[] ptr[i];
        }
    }
    return  9;
}

compiled it as
CC -m64 -g 

现在,当我运行它时,我可以看到进程大小不断增加,并且在达到系统内存限制时进程崩溃。我使用 truss 跟踪它,我只能看到 brk 系统调用。在搜索一些 oracle 站点时,我设置了 LD_PRELOAD=libmapmalloc.so,然后进程大小是恒定的。truss 显示这次它使用 malloc 来映射匿名内存页面。

另一方面,我也尝试在 RHEL Linux 2.6 x86 机器上看到这种行为,它也使用了 truss,但进程大小是恒定的。

在第一种情况下,我不了解行为或 Solaris,它使用 brk 来增加数据段的大小,但是当我进行删除时,它并没有减少它。有人可以解释一下为什么 solaris 这样做吗?

那么 linux 在这里做些什么来保持进程大小不变,因为它也使用相同的系统调用。

谢谢尼拉吉·拉蒂

4

2 回答 2

0

让我引用官方的 oracle 文档

请注意,执行 free() 后,释放的空间可供应用程序进一步分配,而不是返回给系统。只有当应用程序终止时,内存才会返回给系统。

于 2013-08-08T19:45:42.877 回答
0

我读过那篇文章,但正如您所见,我的分配模式几乎是不变的,我分配了大约 20MB 的内存,然后释放它,然后再次分配 20MB 的内存。

因此,如果 Solaris libc 正在重用释放的内存,那么它不应该一次又一次地调用 brk 并且进程大小应该保持不变,但在这里它会不断增长,并且似乎释放的内存永远不会被重用。

谢谢尼拉吉·拉蒂

于 2013-08-08T20:22:00.310 回答