����Linux�Ż�
Linux����

Ϊʲôlinux�¶��̳߳���������������ڴ�

����ʱ��:2016-11-17 11:56:40��Դ:blog.csdn.net/chen19870707����:chen19870707
�����Ϸ��������Ӫ�����з������ڴ��Ż�������һ���dz���������⣬���ǵ���֤��������AuthServer�����������������SDK�򽻵������ڲ�����curl�����ķ�ʽ���������↑��128���̣߳���ֵ���ÿ�θ�������ʱ��ռ�õ������ڴ���2.3G��Ȼ��ÿ�δ�����Ϣ������64M�����ӵ�4.4G�Ͳ��������ˣ��������Dz���Ԥ����ķ�ʽ�����߳��ڲ�����û�д����ڴ棬��ô��Щ�ڴ浽���Ǵ��������أ����˰�˼������⡣
Ϊʲôlinux�¶��̳߳���������������ڴ�
 
1.̽��
һ��ʼ�����ų����ڴ�й¶��������ÿ�ζ�й¶64M�ڴ���ô�ɺϣ�Ϊ��֤���ҵĹ۵㣬���ȣ���ʹ����valgrind��
1: valgrind --leak-check=full --track-fds=yes --log-file=./AuthServer.vlog &
Ȼ���������ԣ������ڴ治�����ӣ���Ȼvalgrind��ʾû���κ��ڴ�й¶�����������˺ܶ�Σ��������������
�ڶ��ʹ��valgrind�޹��Ժ��ҿ�ʼ���ɳ����ڲ��Dz����õ�mmap֮��ĵ���,����ʹ��strace��mmap,brk��ϵͳ�����ļ�⣺
1: strace -f -e"brk,mmap,munmap" -p $(pidof AuthServer)
�������£�
1: [pid 19343] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f53c8ca9000
2: [pid 19343] munmap(0x7f53c8ca9000, 53833728) = 0
3: [pid 19343] munmap(0x7f53d0000000, 13275136) = 0
4: [pid 19343] mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f53d04a8000
5: Process 19495 attached
�Ҽ����һ��trace�ļ�Ҳû�з��ִ����ڴ�mmap������������brk����������ڴ�����Ҳ�������Ǹо�������û�з����ˣ�Ȼ�����Dz����ļ�����������ڴ�ռ���ˣ�ע�͵��˴��������ж�д��־�Ĵ��룬�����ڴ���Ȼ���ӣ��ų���������ܡ�
 
2.���һ��
�������ҿ�ʼ����thread��������ʼ���ԣ��ڲ��Ե�ʱ��żȻ����һ������ֵ������Ǿ���������̴�����һ���̲߳����ڸ��߳��ڷ���һ����С���ڴ�1k���������������ڴ���������64M��Ȼ���ٷ��䣬�ڴ�Ͳ������ˡ����Դ������£�
1: #include <iostream>
2: #include <stdio.h>
3: #include <stdlib.h>
4: #include <unistd.h>
5: using namespace std;
6:  
7: volatile bool start = 0;
8:  
9:  
10: void* thread_run( void* )
11: {
12:  
13:while(1)
14:{
15: if(start)
16: {
17: cout << "Thread malloc" << endl;
18: char *buf = new char[1024];
19: start = 0;
20: }
21: sleep(1);
22:}
23: }
24:  
25: int main()
26: {
27: pthread_t th;
28:  
29: getchar();
30: getchar();
31: pthread_create(&th, 0, thread_run, 0);
32:  
33: while((getchar()))
34: {
35: start  = 1;
36: }
37:  
38:  
39: return 0;
40: }
�����н������ͼ���տ�ʼʱ������ռ�������ڴ�14M������0���������̣߳������ڴ�ﵽ23M�������ӵ�10M���̶߳�ջ�Ĵ�С���鿴�������̶߳�ջ��С����ulimit –s������һ������1���������1k�ڴ棬������������64M�����ڴ棬֮��������2��3�����ٴη���1k���ڴ�����ٱ仯��
Ϊʲôlinux�¶��̳߳���������������ڴ�
������������ϲ����������ǰѧϰ���ȸ��Tcmalloc������ÿ���̶߳����Լ��Ļ�������������߳��ڴ����ľ����������°��glibcͬ��ѧϰ��������ɣ����Dz鿴pmap $(pidof main) �鿴�ڴ���������£�
Ϊʲôlinux�¶��̳߳���������������ڴ�
��ע��65404��һ�У����ּ������������ټ�����������һ�У���������132���������ӵ��Ǹ�64M������������thread���������ͻ�������thread������Ӧ��65404���ڴ�顣
 
3.�ٸ��ʵ�
����һ�������ʹ���鿴������֪����ԭ����glibc��malloc�����ﵷ����glibc �汾����2.11�Ķ�����������⣺��redhat �Ĺٷ��ĵ��ϣ�
Red Hat Enterprise Linux 6 features version 2.11 of glibc, providing many features and enhancements, including... An enhanced dynamic memory allocation (malloc) behaviour enabling higher scalability across many sockets and cores.This is achieved by assigning threads their own memory pools and by avoiding locking in some situations. The amount of additional memory used for the memory pools (if any) can be controlled using the environment variables MALLOC_ARENA_TEST and MALLOC_ARENA_MAX. MALLOC_ARENA_TEST specifies that a test for the number of cores is performed once the number of memory pools reaches this value. MALLOC_ARENA_MAX sets the maximum number of memory pools used, regardless of the number of cores.
The developer, Ulrich Drepper, has a much deeper explanation on his blog:
Before, malloc tried to emulate a per-core memory pool. Every time when contention for all existing memory pools was detected a new pool is created. Threads stay with the last used pool if possible... This never worked 100% because a thread can be descheduled while executing a malloc call. When some other thread tries to use the memory pool used in the call it would detect contention. A second problem is that if multiple threads on multiple core/sockets happily use malloc without contention memory from the same pool is used by different cores/on different sockets. This can lead to false sharing and definitely additional cross traffic because of the meta information updates. There are more potential problems not worth going into here in detail.
The changes which are in glibc now create per-thread memory pools. This can eliminate false sharing in most cases. The meta data is usually accessed only in one thread (which hopefully doesn’t get migrated off its assigned core). To prevent the memory handling from blowing up the address space use too much the number of memory pools is capped. By default we create up to two memory pools per core on 32-bit machines and up to eight memory per core on 64-bit machines. The code delays testing for the number of cores (which is not cheap, we have to read /proc/stat) until there are already two or eight memory pools allocated, respectively.
While these changes might increase the number of memory pools which are created (and thus increase the address space they use) the number can be controlled. Because using the old mechanism there could be a new pool being created whenever there are collisions the total number could in theory be higher. Unlikely but true, so the new mechanism is more predictable.
... Memory use is not that much of a premium anymore and most of the memory pool doesn’t actually require memory until it is used, only address space... We have done internally some measurements of the effects of the new implementation and they can be quite dramatic.
New versions of glibc present in RHEL6 include a new arena allocator design. In several clusters we've seen this new allocator cause huge amounts of virtual memory to be used, since when multiple threads perform allocations, they each get their own memory arena. On a 64-bit system, these arenas are 64M mappings, and the maximum number of arenas is 8 times the number of cores. We've observed a DN process using 14GB of vmem for only 300M of resident set. This causes all kinds of nasty issues for obvious reasons.
Setting MALLOC_ARENA_MAX to a low number will restrict the number of memory arenas and bound the virtual memory, with no noticeable downside in performance - we've been recommending MALLOC_ARENA_MAX=4. We should set this in Hadoop-env.sh to avoid this issue as RHEL6 becomes more and more common.
�ܽ�һ�£�glibcΪ�˷����ڴ�����ܵ����⣬ʹ���˺ܶ����arena��memory pool,ȱʡ������64bit������ÿһ��arenaΪ64M��һ�����̿�������� cores * 8��arena��������Ļ�����4�˵ģ���ô��������4 * 8 = 32��arena��Ҳ����ʹ��32 * 64 = 2048M�ڴ档 ��Ȼ��Ҳ����ͨ�����û����������ı�arena������.����export MALLOC_ARENA_MAX=1
hadoop�Ƽ������ֵ����Ϊ4����Ȼ�ˣ���Ȼ�Ƕ�˵Ļ�������arena��������Ϊ�˽�����߳��ڴ���侺�������⣬��ô����Ϊcpu�˵���������Ҳ��һ��������ѡ���������ֵ�Ժ�����ܶ���ij�����һ��ѹ�����ԣ����Կ����ı�arena�������Ƿ��Գ����������Ӱ�졣
mallopt(M_ARENA_MAX, xxx)���������ڳ�������������������������ô���Ե���mallopt(M_ARENA_MAX, xxx)��ʵ�֣���������AuthServer������Ԥ����ķ�ʽ���ڸ����߳��ڲ�û�з����ڴ棬���Բ���Ҫ�����Ż����ڳ�ʼ����ʱ�����mallopt(M_ARENA_MAX, 1)����ص�������Ϊ0����ʾϵͳ��CPU�����Զ����á�
 
4.���ⷢ��
�뵽tcmallocС����Ŵ��߳��Լ����ڴ�ط��䣬���ڴ���Ȼ��������������䣬��֪��glibc�������Ƶģ����ǽ�����������߳�ÿ�η�����ڴ��1k����Ϊ1M����Ȼ�������ϣ��ٷ�����64M����Ȼÿ�ζ�������1M���ɴ˿ɼ����°� glibc��ȫ�����tcmalloc��˼�롣
Ϊʲôlinux�¶��̳߳���������������ڴ�
æ�˼�����������ڽ���ˣ������ã�ͨ���������������֪������Ϊһ������������Ա����������������Ͳ���ϵͳ�ںˣ�����ȫ���ϸ�ģ��Ժ�Ҫ��ǿ�ⷽ���ѧϰ��
 
�������ø��µ�ַ��//m.ajphoenix.com/linux/26082.html