一个简单的pthread测试用例分配以下RAM,由顶部的VIRT列测量:
没有pthread /堆使用情况:4224 kB
使用pthread但没有堆:14716 kB
在main中使用pthread和堆(但不是线程):23632 kB
在main和thread中使用pthread和heap:89168 kB
为什么会分配如此多的RAM? valgrind --page-as-heap = yes显示峰值堆分配为127MB。
我读到线程共享一个堆,那么为什么在pthread中使用堆时会出现大跳?该代码稍后将针对具有非常有限资源的嵌入式系统,因此理解这些分配非常重要。
使用以下内容编译(Ubuntu 16.04上的g ++版本5.4.0):
g++ -O2 -pthread thread.cpp
thread.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;
}
答案 0 :(得分:0)
我读到线程共享一堆
正确。
那么为什么在pthread中使用堆时会出现大跳?
GLIBC(和许多其他)malloc实现使用每个线程的竞技场来避免所有线程争用单个堆锁。
每个线程中的第一个malloc(1)
将创建一个全新的竞技场(通常通过mmap
)。竞技场的大小是一个实现细节,2或4 MB并非不合理。
由顶部
的VIRT列测量的RAM
这不是一个好的衡量标准。程序可以具有巨大的 virt 大小,但使用非常少的实际内存。只是试着映射1 GB内存但不要触摸它 - 你的程序VIRT
将会通过屋顶,但系统可用的内存根本不会减少。
该代码稍后将以非常有限的资源为目标嵌入系统,因此理解这些分配非常重要。
在这种情况下,您需要比top
更好的工具。准确计算Linux上的实际内存使用量有点棘手。您可以先查看/proc/$pid/smaps
。