6. Memory management

  1. HAProxy uses a simple and fast pool-based memory management. Since it relies on
  2. a small number of different object types, it's much more efficient to pick new
  3. objects from a pool which already contains objects of the appropriate size than
  4. to call malloc() for each different size. The pools are organized as a stack or
  5. LIFO, so that newly allocated objects are taken from recently released objects
  6. still hot in the CPU caches. Pools of similar sizes are merged together, in
  7. order to limit memory fragmentation.
  8.  
  9. By default, since the focus is set on performance, each released object is put
  10. back into the pool it came from, and allocated objects are never freed since
  11. they are expected to be reused very soon.
  12.  
  13. On the CLI, it is possible to check how memory is being used in pools thanks to
  14. the "show pools" command :
  15.  
  16. > show pools
  17. Dumping pools usage. Use SIGQUIT to flush them.
  18. - Pool cache_st (16 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9ccc40=03 [SHARED]
  19. - Pool pipe (32 bytes) : 5 allocated (160 bytes), 5 used, 0 failures, 2 users, @0x9ccac0=00 [SHARED]
  20. - Pool comp_state (48 bytes) : 3 allocated (144 bytes), 3 used, 0 failures, 5 users, @0x9cccc0=04 [SHARED]
  21. - Pool filter (64 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 3 users, @0x9ccbc0=02 [SHARED]
  22. - Pool vars (80 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9ccb40=01 [SHARED]
  23. - Pool uniqueid (128 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9cd240=15 [SHARED]
  24. - Pool task (144 bytes) : 55 allocated (7920 bytes), 55 used, 0 failures, 1 users, @0x9cd040=11 [SHARED]
  25. - Pool session (160 bytes) : 1 allocated (160 bytes), 1 used, 0 failures, 1 users, @0x9cd140=13 [SHARED]
  26. - Pool h2s (208 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9ccec0=08 [SHARED]
  27. - Pool h2c (288 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9cce40=07 [SHARED]
  28. - Pool spoe_ctx (304 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9ccf40=09 [SHARED]
  29. - Pool connection (400 bytes) : 2 allocated (800 bytes), 2 used, 0 failures, 1 users, @0x9cd1c0=14 [SHARED]
  30. - Pool hdr_idx (416 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9cd340=17 [SHARED]
  31. - Pool dns_resolut (480 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9ccdc0=06 [SHARED]
  32. - Pool dns_answer_ (576 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9ccd40=05 [SHARED]
  33. - Pool stream (960 bytes) : 1 allocated (960 bytes), 1 used, 0 failures, 1 users, @0x9cd0c0=12 [SHARED]
  34. - Pool requri (1024 bytes) : 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9cd2c0=16 [SHARED]
  35. - Pool buffer (8030 bytes) : 3 allocated (24090 bytes), 2 used, 0 failures, 1 users, @0x9cd3c0=18 [SHARED]
  36. - Pool trash (8062 bytes) : 1 allocated (8062 bytes), 1 used, 0 failures, 1 users, @0x9cd440=19
  37. Total: 19 pools, 42296 bytes allocated, 34266 used.
  38.  
  39. The pool name is only indicative, it's the name of the first object type using
  40. this pool. The size in parenthesis is the object size for objects in this pool.
  41. Object sizes are always rounded up to the closest multiple of 16 bytes. The
  42. number of objects currently allocated and the equivalent number of bytes is
  43. reported so that it is easy to know which pool is responsible for the highest
  44. memory usage. The number of objects currently in use is reported as well in the
  45. "used" field. The difference between "allocated" and "used" corresponds to the
  46. objects that have been freed and are available for immediate use. The address
  47. at the end of the line is the pool's address, and the following number is the
  48. pool index when it exists, or is reported as -1 if no index was assigned.
  49.  
  50. It is possible to limit the amount of memory allocated per process using the
  51. "-m" command line option, followed by a number of megabytes. It covers all of
  52. the process's addressable space, so that includes memory used by some libraries
  53. as well as the stack, but it is a reliable limit when building a resource
  54. constrained system. It works the same way as "ulimit -v" on systems which have
  55. it, or "ulimit -d" for the other ones.
  56.  
  57. If a memory allocation fails due to the memory limit being reached or because
  58. the system doesn't have any enough memory, then haproxy will first start to
  59. free all available objects from all pools before attempting to allocate memory
  60. again. This mechanism of releasing unused memory can be triggered by sending
  61. the signal SIGQUIT to the haproxy process. When doing so, the pools state prior
  62. to the flush will also be reported to stderr when the process runs in
  63. foreground.
  64.  
  65. During a reload operation, the process switched to the graceful stop state also
  66. automatically performs some flushes after releasing any connection so that all
  67. possible memory is released to save it for the new process.