我得到了我所问问题的答案。
应用程序内存分配器:
C 和 C++ 开发人员必须手动管理内存分配和释放内存。默认内存分配器位于 libc 库中。
Libc 请注意,在执行 free() 之后,释放的空间可供应用程序进一步分配,而不是返回给系统。只有当应用程序终止时,内存才会返回给系统。这就是为什么应用程序的进程大小通常永远不会减少的原因。但是对于长时间运行的应用程序,应用程序进程大小通常保持在稳定状态,因为释放的内存可以被重用。如果不是这种情况,那么很可能是应用程序正在泄漏内存,即分配的内存已使用但在不再使用时从未释放,并且指向已分配内存的指针没有被应用程序跟踪 - 基本上丢失了。
当并发 malloc 或 free 操作频繁发生时,libc 中的默认内存分配器不适用于多线程应用程序,特别是对于多线程 C++ 应用程序。这是因为创建和销毁 C++ 对象是 C++ 应用程序开发风格的一部分。当使用默认的 libc 分配器时,堆由单个堆锁保护,由于 malloc 或空闲操作期间的严重锁争用,导致默认分配器无法针对多线程应用程序进行扩展。使用 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++ 符号名称。(Sun Studio 软件提供了 c++filt 实用程序。)如果应用程序不是 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。