一个简单的 pthread 测试用例根据顶部的 VIRT 列分配以下 RAM:
无 pthread/heap 使用:4224 kB
使用 pthread 但不使用堆:14716 kB
在主线程中使用 pthread 和堆(但不是线程):23632 kB
在主线程中使用 pthread 和堆:89168 kB
为什么要分配这么多内存? valgrind --page-as-heap=yes 显示 127MB 的峰值堆分配。
我读到线程共享一个堆,那么为什么在 pthread 中使用堆时会有很大的跳跃?该代码稍后将针对资源非常有限的嵌入式系统,因此了解这些分配非常重要。
使用以下内容编译(Ubuntu 16.04 上的 g++ 版本 5.4.0):
g++ -O2 -pthread thread.cpp
线程.cpp:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#define USE_THREAD
#define USE_HEAP_IN_MAIN
#define USE_HEAP_IN_THREAD
int *arr_thread;
int *arr_main;
void *use_heap(void *arg){
#ifdef USE_HEAP_IN_THREAD
arr_thread=new int[10];
arr_thread[0]=1234;
#endif
usleep(10000000);
}
int main() {
pthread_t t1;
#ifdef USE_HEAP_IN_MAIN
arr_main=new int[10];
arr_main[0]=5678;
#endif
#ifdef USE_THREAD
pthread_create(&t1, NULL, &use_heap, NULL);
pthread_join(t1,NULL);
#else
usleep(10000000);
#endif
return 0;
}
- 编辑为使用全局指针来演示 -O2 的效果。
最佳答案
I read that threads share a heap
正确。
so why the big jump when using the heap from within the pthread?
GLIBC(以及许多其他)malloc 实现使用每线程 arena 来避免所有线程争用单个堆锁。
每个线程中的第一个 malloc(1)
将创建一个全新的竞技场(通常通过 mmap
)。 arena 的大小是一个实现细节,2 或 4 MB 并非不合理。
RAM as measured by the VIRT column of top
这不是一个好的衡量标准。一个程序可以有很大的 virt 大小,但实际使用的内存却很少。只需尝试 mmap 1 GB 内存但不要触及它——您的程序 VIRT
将达到顶峰,但系统可用内 stub 本不会减少。
The code will later target an embedded system with very limited resources so understanding these allocations is quite important.
在那种情况下,您需要比 top
更好的工具。准确计算 Linux 上的实际 内存使用量有些棘手。您可以从查看 /proc/$pid/smaps
开始。
关于c++ - 在 pthread 中使用堆分配 >100MB 的 RAM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44033310/