Hi Godbach, On Fri, Jul 19, 2013 at 12:21:23PM +0800, Godbach wrote: > Hi Willy, > > In my opinion, haproxy will full size memory after allocating that for > fdtab and fdinfo since calloc is used. But after I started haproxy with > maxconn 1,048,576 wiht lastest snapshot, the result from `top` command > as below: > PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND > 17835 root 20 0 165m 1184 872 S 0.0 0.0 0:00.00 haproxy > > Since each conn will cause more than 150 bytes allocated during startup, > it will use more than 150Mbytes for 1,048,576 conns. But RES is very > little on the above. > > Then I run a simple program which also called calloc to alloc 300Mbytes > meomory, and the reuslt as below: > PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND > 17797 root 20 0 304m 300m 332 S 0.0 7.7 0:00.15 tmem > The RES is 300M just as it supposed to be. > > At last, I have done another test which called memset() explicitly after > allocating memory for fdtab and fdinfo, the codes as below: > > fdinfo = (struct fdinfo *)calloc(1, > sizeof(struct fdinfo) * > (global.maxsock)); > fdtab = (struct fdtab *)calloc(1, > sizeof(struct fdtab) * > (global.maxsock)); > + memset(fdinfo, 0x00, sizeof(struct fdinfo) * (global.maxsock)); > + memset(fdtab, 0x00, sizeof(struct fdtab) * (global.maxsock)); > > I run haproxy again and the top result is as below: > PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND > 17877 root 20 0 165m 101m 928 S 0.0 2.6 0:00.05 haproxy.memset > > Here RES is 101M?? just nearly the same as the memory required by both > fdinfo and fdtab which is 100Mbytes(100bytes/conn, 100Mbytes for 1M conns). > > It seems that haproxy has not used full size memory it requires for > startup, I was confused by the behavior of calloc since I have not > define CONFIG_HAP_CALLOC either. Did I miss something or misunderstand > calloc?
You should strace it. I'm sure you'll see an mmap() call that matches the size of your allocation, meaning that the libc has decided to use this instead of sbrk() to allocate the area. Then by definition all the area will return zeroes, so the libc does not need to perform a memset on it. The issue however is that we believe the memory is granted but we can fail to use it on low memory condition. If this is what happens, I'd prefer that we explicitly use memset on these critical elements such as fdtab etc... to guarantee the memory is allocated. Best regards, Willy