From a8506edbb931867d881d5b854f7d15cb74e9086f Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Fri, 31 May 2024 01:28:35 -0700 Subject: [PATCH] build: link jemalloc by default to reduce heap fragmentation The QML engine and the quickshell reloader both cause large amounts of heap fragmentation that stacks up over time, leading to a perceived memory leak. Jemalloc is able to handle the fragmentation much better, leading to lower user facing memory usage. --- CMakeLists.txt | 9 +++++++++ README.md | 5 ++++- default.nix | 17 +++++++++++------ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d17758b..e790ec0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ option(BUILD_TESTING "Build tests" OFF) option(ASAN "Enable ASAN" OFF) option(FRAME_POINTERS "Always keep frame pointers" ${ASAN}) +option(USE_JEMALLOC "Use jemalloc over the system malloc implementation" ON) option(NVIDIA_COMPAT "Workarounds for nvidia gpus" OFF) option(SOCKETS "Enable unix socket support" ON) option(WAYLAND "Enable wayland support" ON) @@ -23,6 +24,7 @@ option(SERVICE_PIPEWIRE "PipeWire service" ON) option(SERVICE_MPRIS "Mpris service" ON) message(STATUS "Quickshell configuration") +message(STATUS " Jemalloc: ${USE_JEMALLOC}") message(STATUS " NVIDIA workarounds: ${NVIDIA_COMPAT}") message(STATUS " Build tests: ${BUILD_TESTING}") message(STATUS " Sockets: ${SOCKETS}") @@ -137,3 +139,10 @@ if (NVIDIA_COMPAT) endif() add_subdirectory(src) + +if (USE_JEMALLOC) + find_package(PkgConfig REQUIRED) + # IMPORTED_TARGET not working for some reason + pkg_check_modules(JEMALLOC REQUIRED jemalloc) + target_link_libraries(quickshell PRIVATE ${JEMALLOC_LIBRARIES}) +endif() diff --git a/README.md b/README.md index c17af3a8..173ddd17 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,13 @@ To build quickshell at all, you will need the following packages (names may vary - just - cmake - ninja +- pkg-config - Qt6 [ QtBase, QtDeclarative ] +Jemalloc is recommended, in which case you will need: +- jemalloc + To build with wayland support you will additionally need: -- pkg-config - wayland - wayland-scanner (may be part of wayland on some distros) - wayland-protocols diff --git a/default.nix b/default.nix index 0985d843..048e181e 100644 --- a/default.nix +++ b/default.nix @@ -8,6 +8,7 @@ cmake, ninja, qt6, + jemalloc, wayland, wayland-protocols, xorg, @@ -29,7 +30,8 @@ enableX11 ? true, enablePipewire ? true, nvidiaCompat ? false, - svgSupport ? true, # you almost always want this + withQtSvg ? true, # svg support + withJemalloc ? true, # masks heap fragmentation }: buildStdenv.mkDerivation { pname = "quickshell${lib.optionalString debug "-debug"}"; version = "0.1.0"; @@ -39,8 +41,8 @@ cmake ninja qt6.wrapQtAppsHook - ] ++ (lib.optionals enableWayland [ pkg-config + ] ++ (lib.optionals enableWayland [ wayland-protocols wayland-scanner ]); @@ -49,10 +51,11 @@ qt6.qtbase qt6.qtdeclarative ] + ++ (lib.optional withJemalloc jemalloc) + ++ (lib.optional withQtSvg qt6.qtsvg) ++ (lib.optionals enableWayland [ qt6.qtwayland wayland ]) - ++ (lib.optionals enableX11 [ xorg.libxcb ]) - ++ (lib.optionals svgSupport [ qt6.qtsvg ]) - ++ (lib.optionals enablePipewire [ pipewire ]); + ++ (lib.optional enableX11 xorg.libxcb) + ++ (lib.optional enablePipewire pipewire); QTWAYLANDSCANNER = lib.optionalString enableWayland "${qt6.qtwayland}/libexec/qtwaylandscanner"; @@ -67,7 +70,9 @@ cmakeFlags = [ "-DGIT_REVISION=${gitRev}" - ] ++ lib.optional (!enableWayland) "-DWAYLAND=OFF" + ] + ++ lib.optional (!withJemalloc) "-DUSE_JEMALLOC=OFF" + ++ lib.optional (!enableWayland) "-DWAYLAND=OFF" ++ lib.optional nvidiaCompat "-DNVIDIA_COMPAT=ON" ++ lib.optional (!enablePipewire) "-DSERVICE_PIPEWIRE=OFF";