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


Reply via email to