在Solaris/Linux中释放已分配的内存

4
我编写了一个小程序,并在Solaris/Linux平台下编译它,以测量将此代码应用于我的应用程序的性能。该程序的编写方式如下:首先使用sbrk(0)系统调用获取堆区域的基地址,然后使用malloc系统调用分配了1.5 GB的内存,接着使用memcpy系统调用将1.5 GB的内容复制到已分配的内存区域中,最后释放了已分配的内存。释放后,再次使用sbrk(0)系统调用查看堆大小。这就是我有点困惑的地方。在Solaris中,即使我释放了分配的内存(近1.5 GB),进程的堆大小仍然很大。但是我在Linux上运行相同的应用程序,在释放后发现进程的堆大小等于1.5 GB内存分配之前的堆内存大小。我知道Solaris不会立即释放内存,但我不知道如何调整Solaris内核以在free()系统调用后立即释放内存。为什么在Linux下我没有同样的问题呢?
1个回答

4

我得到了我提出的问题的答案。

应用程序内存分配器:

C和C++开发人员必须手动管理内存分配和释放。默认的内存分配器在libc库中。

libc 请注意,在执行free()后,释放的空间将可供应用程序进一步分配使用,而不会返回给系统。只有当应用程序终止时,内存才会返回给系统。这就是为什么应用程序的进程大小通常永远不会减小。但对于长时间运行的应用程序,应用程序进程大小通常保持稳定状态,因为释放的内存可以被重复使用。如果不是这种情况,则很可能应用程序泄漏内存,即在不再使用时未释放已分配的内存,并且应用程序未跟踪已分配内存的指针--基本上是丢失了。

在多线程应用程序中频繁发生并发malloc或free操作时,默认的libc内存分配器不适用于多线程应用程序,特别是对于多线程C++应用程序。这是因为创建和销毁C++对象是C++应用程序开发风格的一部分。当使用默认的libc分配器时,堆由单个堆锁保护,导致默认分配器在malloc或free操作期间由于重量级锁争用而不可扩展。可以使用Solaris工具轻松检测此问题,如下所示。

首先,使用prstat -mL -p查看应用程序是否在锁上花费了大量时间;查看LCK列。例如:

-bash-3.2# prstat -mL -p 14052
   PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID
 14052 root     0.6 0.7 0.0 0.0 0.0  35 0.0  64 245  13 841   0 test_vector_/721
 14052 root     1.0 0.0 0.0 0.0 0.0  35 0.0  64 287   5 731   0 test_vector_/941
 14052 root     1.0 0.0 0.0 0.0 0.0  35 0.0  64 298   3 680   0 test_vector_/181
 14052 root     1.0 0.1 0.0 0.0 0.0  35 0.0  64 298   3  1K   0 test_vector_/549
 ....

这表明该应用程序约花费35%的时间等待锁。

然后,使用plockstat(1M)工具查找应用程序正在等待的锁。例如,使用进程ID 14052跟踪应用程序5秒钟,然后使用c++filt实用程序过滤输出以解码C ++符号名称。 (c++filt实用程序随附于Sun Studio软件中。)如果应用程序不是C ++应用程序,则不需要通过c++filt进行过滤。

-bash-3.2#  plockstat -e 5 -p 14052 | c++filt
Mutex block
Count     nsec   Lock                         Caller
-------------------------------------------------------------------------------
 9678 166540561 libc.so.1‘libc_malloc_lock   libCrun.so.1‘void operator 
 delete(void*)+0x26

 5530 197179848 libc.so.1‘libc_malloc_lock   libCrun.so.1‘void*operator 
 new(unsigned)+0x38

......

从上面的内容可以看出,堆锁 libc_malloc_lock 被大量争夺,这很可能是导致扩展问题的原因。解决 libc 分配器的扩展问题的方法是使用一个改进的内存分配器,比如 libumem 库。
另外请访问:http://developers.sun.com/solaris/articles/solaris_memory.html 感谢所有试图回答我的问题的人, Santhosh.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接