From 684732bf0931223d8604bd190fea72b9c85b4210 Mon Sep 17 00:00:00 2001 From: Roland Bosa Date: Wed, 12 Jun 2024 21:48:19 -0700 Subject: [PATCH 1/3] Reduce memory usage of renderd The core issue seems to be the memory management combined with the memory usage pattern of renderd. The glib-provided heap implementation somehow fails to give back memory to the system, but instead keeps on growing the data segment until the system decides to kill the process. The jemalloc implementation puts allocations into arenas and once they are freed (and some time has passed), they are given back to the system and seem to reduce the RSS size of the process. This should address/alleviate https://github.com/openstreetmap/mod_tile/issues/181 --- CMakeLists.txt | 7 +++++++ src/CMakeLists.txt | 2 ++ 2 files changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac57efb5..98bd666d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,13 @@ include(GNUInstallDirs) find_package(ICU REQUIRED uc) find_package(Threads REQUIRED) +# Switch to jemalloc (http://jemalloc.net) as the malloc/free +# implementation in renderd. +# Should address https://github.com/openstreetmap/mod_tile/issues/181 +find_package(PkgConfig REQUIRED) +pkg_check_modules(JEMALLOC jemalloc) +pkg_search_module(JEMALLOC REQUIRED jemalloc) + find_package(APR REQUIRED) find_package(GLIB 2.50 REQUIRED) find_package(HTTPD 2.4 REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7e62d6d..e1336625 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -179,7 +179,9 @@ set(renderd_SRCS renderd.c request_queue.c ) +# JEMALLOC libraries should come *before* the GLIB libraries. set(renderd_LIBS + ${JEMALLOC_LIBRARIES} ${ICU_LIBRARIES} ${LIBMAPNIK_LIBRARIES} ${RENDER_LIBRARIES} From 1a45dc4a2464aeca6ac708c9f4752d055a4e6045 Mon Sep 17 00:00:00 2001 From: Roland Bosa Date: Fri, 14 Jun 2024 03:11:16 +0000 Subject: [PATCH 2/3] Allow choosing between malloc libraries Default is `glib`, which seems to have issues with increased memory consumption. Alternatives are `jemalloc` and `tcmalloc`. To select a different library, configure the build folder, then run `ccmake ` to configure the option `MALLOC_LIB`. For automated configuration, run, add `-DMALLOC_LIB=jemalloc` or `-DMALLOC_LIB=tcmalloc` to the `cmake` configuration command line. --- CMakeLists.txt | 21 +++++++++++++++------ src/CMakeLists.txt | 16 ++++++++++++++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 98bd666d..8c43e6e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,9 @@ set(USE_CURL ON CACHE BOOL "Add curl support if available (for `store_ro_http_pr set(USE_MEMCACHED ON CACHE BOOL "Add memcached support if available (for `store_memcached.c` backend)") set(USE_RADOS ON CACHE BOOL "Add rados support if available (for `store_rados.c` backend)") +set(MALLOC_LIB "glib" CACHE STRING "Memory Management Library for `renderd`") +set_property(CACHE MALLOC_LIB PROPERTY STRINGS glib jemalloc tcmalloc) + #----------------------------------------------------------------------------- # # Find external dependencies @@ -45,12 +48,18 @@ include(GNUInstallDirs) find_package(ICU REQUIRED uc) find_package(Threads REQUIRED) -# Switch to jemalloc (http://jemalloc.net) as the malloc/free -# implementation in renderd. -# Should address https://github.com/openstreetmap/mod_tile/issues/181 -find_package(PkgConfig REQUIRED) -pkg_check_modules(JEMALLOC jemalloc) -pkg_search_module(JEMALLOC REQUIRED jemalloc) +if (${MALLOC_LIB} STREQUAL "jemalloc") + # Switch to jemalloc (http://jemalloc.net) as the malloc/free + # implementation in renderd. + # Should address https://github.com/openstreetmap/mod_tile/issues/181 + find_package(PkgConfig REQUIRED) + pkg_search_module(JEMALLOC REQUIRED jemalloc) +elseif (${MALLOC_LIB} STREQUAL "tcmalloc") + # Switch to tcmalloc (https://github.com/google/tcmalloc) + # as the malloc/free implementation in renderd. + find_package(PkgConfig REQUIRED) + pkg_search_module(TCMALLOC REQUIRED libtcmalloc) +endif() find_package(APR REQUIRED) find_package(GLIB 2.50 REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1336625..4321bf4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -179,14 +179,26 @@ set(renderd_SRCS renderd.c request_queue.c ) -# JEMALLOC libraries should come *before* the GLIB libraries. + set(renderd_LIBS - ${JEMALLOC_LIBRARIES} ${ICU_LIBRARIES} ${LIBMAPNIK_LIBRARIES} ${RENDER_LIBRARIES} ${STORE_LIBRARIES} ) + +if ("${MALLOC_LIB}" STREQUAL "jemalloc") + message(STATUS "Using 'jemalloc' for memory management") + # JEMALLOC libraries should come *before* the GLIB libraries. + list(PREPEND renderd_LIBS ${JEMALLOC_LIBRARIES}) +elseif ("${MALLOC_LIB}" STREQUAL "tcmalloc") + message(STATUS "Using 'tcmalloc' for memory management") + # TCMALLOC libraries should come *before* the GLIB libraries. + list(PREPEND renderd_LIBS ${TCMALLOC_LIBRARIES}) +else() + message(STATUS "Using 'glib' for memory managment") +endif() + add_executable(renderd ${renderd_SRCS}) target_link_libraries(renderd ${renderd_LIBS}) From b3b39bc7ff50e563b1f7f5b9c7a880c42657a4c1 Mon Sep 17 00:00:00 2001 From: David Hummel <6109326+hummeltech@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:31:20 -0700 Subject: [PATCH 3/3] Minor changes --- CMakeLists.txt | 32 ++++++++++++++++---------------- src/CMakeLists.txt | 20 +++++--------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c43e6e9..81fe49b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,9 +32,8 @@ set(USE_CAIRO ON CACHE BOOL "Add cairo support if available (for `store_ro_compo set(USE_CURL ON CACHE BOOL "Add curl support if available (for `store_ro_http_proxy.c` backend)") set(USE_MEMCACHED ON CACHE BOOL "Add memcached support if available (for `store_memcached.c` backend)") set(USE_RADOS ON CACHE BOOL "Add rados support if available (for `store_rados.c` backend)") - -set(MALLOC_LIB "glib" CACHE STRING "Memory Management Library for `renderd`") -set_property(CACHE MALLOC_LIB PROPERTY STRINGS glib jemalloc tcmalloc) +set(MALLOC_LIB "libc" CACHE STRING "Memory Management Library for `renderd`") +set_property(CACHE MALLOC_LIB PROPERTY STRINGS "libc" "jemalloc" "mimalloc" "tcmalloc") #----------------------------------------------------------------------------- # @@ -48,19 +47,6 @@ include(GNUInstallDirs) find_package(ICU REQUIRED uc) find_package(Threads REQUIRED) -if (${MALLOC_LIB} STREQUAL "jemalloc") - # Switch to jemalloc (http://jemalloc.net) as the malloc/free - # implementation in renderd. - # Should address https://github.com/openstreetmap/mod_tile/issues/181 - find_package(PkgConfig REQUIRED) - pkg_search_module(JEMALLOC REQUIRED jemalloc) -elseif (${MALLOC_LIB} STREQUAL "tcmalloc") - # Switch to tcmalloc (https://github.com/google/tcmalloc) - # as the malloc/free implementation in renderd. - find_package(PkgConfig REQUIRED) - pkg_search_module(TCMALLOC REQUIRED libtcmalloc) -endif() - find_package(APR REQUIRED) find_package(GLIB 2.50 REQUIRED) find_package(HTTPD 2.4 REQUIRED) @@ -106,6 +92,20 @@ if(NOT HAVE_POW) find_library(MATH_LIBRARY m REQUIRED) endif() +if(NOT MALLOC_LIB STREQUAL "libc") + message(STATUS "Using '${MALLOC_LIB}' for memory managment") + if(MALLOC_LIB STREQUAL "jemalloc") + # jemalloc (http://jemalloc.net) + find_library(MALLOC_LIBRARY jemalloc REQUIRED) + elseif(MALLOC_LIB STREQUAL "mimalloc") + # mimalloc (https://github.com/microsoft/mimalloc) + find_library(MALLOC_LIBRARY mimalloc REQUIRED) + elseif(MALLOC_LIB STREQUAL "tcmalloc") + # tcmalloc (https://github.com/google/tcmalloc) + find_library(MALLOC_LIBRARY tcmalloc REQUIRED) + endif() +endif() + #----------------------------------------------------------------------------- # # Set variables diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4321bf4c..046e49ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,7 +41,6 @@ set(RENDER_LIBRARIES ${COMMON_LIBRARIES} ${INIPARSER_LIBRARIES} ${MATH_LIBRARY} - Threads::Threads ) set(STORE_SRCS @@ -61,6 +60,11 @@ set(STORE_LIBRARIES ${LIBRADOS_LIBRARIES} ) +if(NOT MALLOC_LIB STREQUAL "libc") + message(STATUS "Prepending '${MALLOC_LIBRARY}' to RENDER_LIBRARIES") + list(PREPEND RENDER_LIBRARIES ${MALLOC_LIBRARY}) +endif() + #----------------------------------------------------------------------------- # # Installed targets @@ -179,26 +183,12 @@ set(renderd_SRCS renderd.c request_queue.c ) - set(renderd_LIBS ${ICU_LIBRARIES} ${LIBMAPNIK_LIBRARIES} ${RENDER_LIBRARIES} ${STORE_LIBRARIES} ) - -if ("${MALLOC_LIB}" STREQUAL "jemalloc") - message(STATUS "Using 'jemalloc' for memory management") - # JEMALLOC libraries should come *before* the GLIB libraries. - list(PREPEND renderd_LIBS ${JEMALLOC_LIBRARIES}) -elseif ("${MALLOC_LIB}" STREQUAL "tcmalloc") - message(STATUS "Using 'tcmalloc' for memory management") - # TCMALLOC libraries should come *before* the GLIB libraries. - list(PREPEND renderd_LIBS ${TCMALLOC_LIBRARIES}) -else() - message(STATUS "Using 'glib' for memory managment") -endif() - add_executable(renderd ${renderd_SRCS}) target_link_libraries(renderd ${renderd_LIBS})