由于RHEL6引入了新的竞技场分配器设计,因为对于单个线程增加了相同数量的竞技场,这导致更多的虚拟内存使用。 RHEL6为每个线程分配单独的内存块。根据我对32/64位系统的理解,每个线程的竞技场数量计算如下:
On 32 Bit system :
Number of Arena = 2 * Number of cores .
On 64 Bit system :
Number of Arena = 8 * Number of cores .
请确认我的理解是否有一些差距。
我的机器有4个内核和64位系统,
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 69
Stepping: 1
CPU MHz: 759.000
BogoMIPS: 4589.41
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3072K
NUMA node0 CPU(s): 0-3
$ uname -a
Linux admin 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
因此每个线程有4 * 8 = 32个竞技场。每个竞技场的最大尺寸为64MB; pet thread虚拟内存可以达到32 * 64 = 2GB(每个线程)。 如果我的理解是正确的,请告诉我。
我创建了一个示例程序。它被分配了1.5 GB的堆内存。
#include <pthread.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
static void *thread(void *arg)
{
int i=0;
char *x[1024];
unsigned int pid;
char str[15];
char cmd[30]="cat /proc/";
pid = getpid();
sprintf(str, "%d", pid);
strcat(cmd,str);
strcat(cmd,"/status");
system(cmd);
for(i=0;i<1536;i++)
{
x[i] = malloc(1*1024*1024);
printf("Memory Allocated %d:\n ",i);
system(cmd);
}
for(i=0;i<1536;i++)
{
*x[i] = 5;
free(x[i]);
}
return NULL;
}
int main(void)
{
unsigned i;
pthread_t t;
pthread_create(&t, NULL, thread, NULL);
pthread_join(t, NULL);
return 0;
}
线程t是堆内存分配小于2GB。但是在分配1GB大约后会产生coredump。有关详细信息,请参阅以下详细信息:
Name: arena
State: S (sleeping)
Tgid: 12511
Ngid: 0
Pid: 12511
PPid: 4417
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
FDSize: 256
Groups: 4 24 27 30 46 108 124 129 1000
VmPeak: 1133924 kB
VmSize: 1133924 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 4568 kB
VmRSS: 4568 kB
VmData: 1127636 kB
VmStk: 136 kB
VmExe: 4 kB
VmLib: 2012 kB
VmPTE: 2092 kB
VmSwap: 0 kB
Threads: 2
SigQ: 0/46560
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000006
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
Seccomp: 0
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1027
nonvoluntary_ctxt_switches: 4
为什么coredump会产生?我的上述理解是不正确的,计算线程最大虚拟内存?
如果达到虚拟内存最大限制,会发生什么后果 请注意我已将ulimit设置为无限
$ ulimit
unlimited