Fix T54287: memory not freed after rendering on Linux.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Wed, 3 Oct 2018 09:10:08 +0000 (11:10 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Wed, 3 Oct 2018 10:09:31 +0000 (12:09 +0200)
With new jemalloc versions memory allocated by threads that then become
inactive is not longer automatically freed. Instead we have to enable a
background thread to do it.

Some testing is needed to find out of this is sufficient, because the
background thread only runs periodically.

build_files/cmake/Modules/FindJeMalloc.cmake
intern/guardedalloc/CMakeLists.txt
intern/guardedalloc/intern/mallocn.c

index 506892b34ba2b2e844a0bf58513546821ef3e0ed..0abe103cd2ea08af4af5810d9051aeb6964645b1 100644 (file)
@@ -53,6 +53,15 @@ FIND_LIBRARY(JEMALLOC_LIBRARY
     lib64 lib
   )
 
+if(JEMALLOC_INCLUDE_DIR)
+  SET(_version_regex "^#define[ \t]+JEMALLOC_VERSION[ \t]+\"([^\"]+)\".*")
+  file(STRINGS "${JEMALLOC_INCLUDE_DIR}/jemalloc.h"
+    JEMALLOC_VERSION REGEX "${_version_regex}")
+  string(REGEX REPLACE "${_version_regex}" "\\1"
+    JEMALLOC_VERSION "${JEMALLOC_VERSION}")
+  unset(_version_regex)
+endif()
+
 # handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE if
 # all listed variables are TRUE
 INCLUDE(FindPackageHandleStandardArgs)
index 10ed42871851ac2f7b6d50f8d2a924c4ec6c868b..7f648cff27c8c97af931512e21800ec8efc7a82b 100644 (file)
@@ -53,6 +53,11 @@ if(WIN32 AND NOT UNIX)
        )
 endif()
 
+# Jemalloc 5.0.0+ needs extra configuration.
+if(WITH_MEM_JEMALLOC AND ("${JEMALLOC_VERSION}" VERSION_GREATER_EQUAL "5.0.0"))
+       add_definitions(-DWITH_JEMALLOC_CONF)
+endif()
+
 blender_add_lib(bf_intern_guardedalloc "${SRC}" "${INC}" "${INC_SYS}")
 
 # Override C++ alloc, optional.
index a95cc9163c421b4c3cc0ce98e4aec82b6504df80..8c17da853e553937ea725955a13c0ba4b19f5f53 100644 (file)
 
 #include "mallocn_intern.h"
 
+#ifdef WITH_JEMALLOC_CONF
+/* If jemalloc is used, it reads this global variable and enables background
+ * threads to purge dirty pages. Otherwise we release memory too slowly or not
+ * at all if the thread that did the allocation stays inactive. */
+const char *malloc_conf = "background_thread:true,dirty_decay_ms:4000";
+#endif
+
 size_t (*MEM_allocN_len)(const void *vmemh) = MEM_lockfree_allocN_len;
 void (*MEM_freeN)(void *vmemh) = MEM_lockfree_freeN;
 void *(*MEM_dupallocN)(const void *vmemh) = MEM_lockfree_dupallocN;