在pthread中使用堆分配> 100MB的RAM

时间:2017-05-17 19:30:51

标签: c++ memory pthreads heap ram

一个简单的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;
}
  • 编辑使用全局ptrs来演示-O2的效果。

1 个答案:

答案 0 :(得分:0)

  

我读到线程共享一堆

正确。

  

那么为什么在pthread中使用堆时会出现大跳?

GLIBC(和许多其他)malloc实现使用每个线程的竞技场来避免所有线程争用单个堆锁。

每个线程中的第一个malloc(1)将创建一个全新的竞技场(通常通过mmap)。竞技场的大小是一个实现细节,2或4 MB并非不合理。

  

由顶部

的VIRT列测量的RAM

这不是一个好的衡量标准。程序可以具有巨大的 virt 大小,但使用非常少的实际内存。只是试着映射1 GB内存但不要触摸它 - 你的程序VIRT将会通过屋顶,但系统可用的内存根本不会减少。

  

该代码稍后将以非常有限的资源为目标嵌入系统,因此理解这些分配非常重要。

在这种情况下,您需要比top更好的工具。准确计算Linux上的实际内存使用量有点棘手。您可以先查看/proc/$pid/smaps