编译器选项:' -std = c ++ 11 -O3 -pthread '
这是一个代码示例
void dummy(void)
{
std::vector<unsigned int> g(1);
int i = 0;
while( i<500000000)
{
++i;
}
}
int main(void)
{
std::thread t1(&dummy);
std::thread t2(&dummy);
std::thread t3(&dummy);
t1.join();
t2.join();
t3.join();
return 0;
}
答案 0 :(得分:7)
每个线程都有自己的堆栈。在Linux上,默认堆栈大小为8 MB。当您第一次开始分配内存时,堆内存分配器实际上可能预先保留一个大块。这个可能解释你看到的每个线程64 MB。
那就是说,当我说“已分配”时,这并不意味着这个内存真的被使用了。分配发生在进程的虚拟内存空间中。这是您在运行VSZ
时在ps
列下看到的内容,或者是在您VIRT
运行时top
下的列RSS
下看到的内容。但Linux知道你可能不会使用大部分分配的内存。因此,当您分配了一块虚拟内存时,Linux不会分配任何物理内存来备份它,直到该进程实际开始写入该内存。进程使用的实际内存量在ps
RES
和top
pthread_create()
下。 Linux允许分配比总共物理内存更多的虚拟内存。
即使您的物理内存耗尽,如果32位系统上有很多线程,每个线程分配8 MB的虚拟内存,您可能会耗尽您的进程的虚拟内存空间(大约2 GB)。虽然C ++的线程库不允许您更改堆栈的大小,但C pthreads库允许您通过向pthread_attr_t
提供使用pthread_attr_setstacksize()
调整的Drawable myIcon = ContextCompat.getDrawable(this,R.drawable.my_vector_drawable);
myIcon.setColorFilter(ContextCompat.getColor(this, R.color.yourcolor));
alertDialogBuilder.setIcon(myIcon);
toolbar.setLogo(myIcon);
toolbar.setNavigationIcon(myIcon);
来执行此操作。另请参阅this stackoverflow question。
答案 1 :(得分:0)
您在上面的评论中为ulimit -s
报告的值确实表明该线程仍然在分配堆栈,即使它是一个空主。在线程中执行的函数调用将需要一个堆栈来传递一个返回地址,假设你在x86上。
@Karrek SB正朝着正确的方向前进。您正在使用的分配器可能会影响程序的堆大小。为了避免重复调用brk或sbrk,分配器通常会请求更大的初始内存块。期望以MB为单位的值是不合理的 - 尤其是在首次初始化分配器时,沿着典型页面边界(例如4,8,32,64等)很好地对齐的值。
要控制分配的内存量,结果可能会有所不同。查看您的分配器是否支持mallopt功能。通过一些试验和错误,您可以减少总体内存占用。否则,你总是可以实现自己的分配器。