Skip to content

Commit f9ec566

Browse files
wezellclaude
andauthored
build(docker): default to jemalloc; install mimalloc; add MS jaz java launcher (#35410)
Installing jemalloc for its profiling — we can see what is eating off-heap mem when an OOM is issued. ## Summary This PR bundles two related runtime-image changes: ### 1. Allocator: jemalloc as default, mimalloc still installed - Install both `libjemalloc2` and `libmimalloc2.0` in the runtime image (`dotCMS/src/main/docker/original/Dockerfile`) and the dev-env image (`docker/dev-env/Dockerfile`). - Switch the default `LD_PRELOAD` in `setenv.sh` from mimalloc to `libjemalloc.so.2`. `LD_PRELOAD` is still overridable at runtime, so operators can swap back to mimalloc via env var without an image change. Context: original issue #32320 adopted mimalloc after jemalloc's upstream archival; since then jemalloc has returned to active development, and we want it back as the default while keeping mimalloc installed for easy A/B. ### 2. JVM launcher: Microsoft `jaz` (Azure Command Launcher for Java) - Add Microsoft's apt repo (`packages-microsoft-prod.deb`) and install `jaz` in the runtime image. - In `setenv.sh`, default `_RUNJAVA` to `jaz` when present. Tomcat honors `_RUNJAVA` in place of `$JRE_HOME/bin/java`. `jaz` is a transparent shim that invokes `java` from `PATH`, adding crash-dump capture and arg validation. - Override path: set `_RUNJAVA=/java/bin/java` to bypass `jaz`. Both changes target diagnostics for native memory and JVM crashes — the same problem space — which is why they ship together. Either piece can be disabled at runtime without rebuilding. ### why jemalloc over mimalloc No clear winner in general. They're both excellent and roughly comparable on real workloads. - **Raw performance:** For pure allocation throughput, mimalloc frequently edges out jemalloc. - **Fragmentation / RSS:** Roughly a tie. Both are far better than glibc. Mimalloc has a slight theoretical edge on small-object workloads. - **Battle-testing on JVMs:** jemalloc wins. It's been the de-facto choice for Cassandra, Elasticsearch, Kafka, Hadoop, and countless JVMs. - **Tooling:** jemalloc wins decisively. Its heap profiler is the reason I suggested it — it's the best open-source tool for answering "what's eating my native memory?" Mimalloc's diagnostics are minimal by comparison. Ref: #32320 ## Test plan - [ ] Confirm image builds successfully (`./mvnw install -pl :dotcms-core -DskipTests` + docker build) - [ ] Start container and verify `ldd` / `/proc/$PID/maps` on the Tomcat process shows `libjemalloc.so.2` preloaded - [ ] Verify both `/usr/lib/<arch>-linux-gnu/libjemalloc.so.2` and `/usr/lib/<arch>-linux-gnu/libmimalloc.so.2` are present in the final image - [ ] Smoke test: run dotCMS, confirm startup is clean and no allocator-related warnings in logs - [ ] Verify `LD_PRELOAD=/usr/lib/.../libmimalloc.so.2` override still works for A/B testing - [ ] Confirm `jaz` is on `PATH` and Tomcat starts via `_RUNJAVA=$(command -v jaz)` (check `ps -ef` shows the jaz wrapper) - [ ] Verify `_RUNJAVA=/java/bin/java` override bypasses jaz cleanly 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3f0d647 commit f9ec566

3 files changed

Lines changed: 30 additions & 11 deletions

File tree

docker/dev-env/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ RUN apt-get update && \
3636
apt-get upgrade -y && \
3737
apt-get install -y --no-install-recommends bash zip unzip wget libtcnative-1\
3838
tzdata tini ca-certificates openssl libapr1 libpq-dev curl gnupg\
39-
vim libarchive-tools postgresql-common libmimalloc2.0 libarchive-tools
39+
vim libarchive-tools postgresql-common libmimalloc2.0 libjemalloc2 libarchive-tools
4040

4141

4242
RUN /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y

dotCMS/src/main/docker/original/Dockerfile

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,30 @@ RUN apt update && \
5353
tzdata \
5454
ca-certificates \
5555
libmimalloc2.0 \
56+
libjemalloc2 \
5657
openssl \
5758
libapr1 \
5859
libarchive-tools \
59-
libpq-dev && \
60+
libpq-dev \
61+
apt-transport-https && \
6062
rm -rf /var/lib/apt/lists/*
6163

62-
# Install PostgreSQL client and pg_dump
63-
RUN apt update && \
64-
apt install -y --no-install-recommends postgresql-common && \
64+
# Install PostgreSQL client, pg_dump and MS jaz (java launcher).
65+
# postgresql-common is installed and purged in the same layer so it does not
66+
# bloat the final image (it is only needed as a script runner for pgdg setup).
67+
RUN apt-get update && \
68+
apt-get install -y --no-install-recommends postgresql-common && \
6569
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \
66-
apt update && \
67-
apt install -y --no-install-recommends postgresql-client-18 && \
68-
/usr/bin/pg_dump --version || exit 1 && \
69-
apt purge -y postgresql-common && \
70+
wget -q "https://packages.microsoft.com/config/ubuntu/$(. /etc/os-release; echo $VERSION_ID)/packages-microsoft-prod.deb" -O packages-microsoft-prod.deb && \
71+
dpkg -i packages-microsoft-prod.deb && \
72+
rm packages-microsoft-prod.deb && \
73+
apt-get update && \
74+
apt-get install -y --no-install-recommends \
75+
postgresql-client-18 \
76+
jaz && \
77+
/usr/bin/pg_dump --version && \
78+
apt-get purge -y postgresql-common && \
79+
apt-get autoremove -y && \
7080
rm -rf /var/lib/apt/lists/*
7181

7282
ARG USER_UID="65001"

dotCMS/src/main/resources/container/tomcat9/bin/setenv.sh

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,17 @@ export DOT_SAMESITE_COOKIES=${DOT_SAMESITE_COOKIES:-"lax"}
104104
export DOT_MAIL_SMTP_HOST=${DOT_MAIL_SMTP_HOST:-"smtp.dotcms.site"}
105105
export DOT_MAIL_SMTP_SSL_PROTOCOLS=${DOT_MAIL_SMTP_SSL_PROTOCOLS:-"TLSv1.2"}
106106

107-
# Set environment variable for mimalloc
108-
export LD_PRELOAD=${LD_PRELOAD:-"/usr/lib/`uname -m`-linux-gnu/libmimalloc.so.2"}
107+
# Preload jemalloc as the default allocator (mimalloc is also installed in the image;
108+
# override LD_PRELOAD at runtime to switch, e.g. .../libmimalloc.so.2)
109+
export LD_PRELOAD=${LD_PRELOAD:-"/usr/lib/`uname -m`-linux-gnu/libjemalloc.so.2"}
110+
111+
# Use Azure Command Launcher for Java (jaz) as the JVM launcher when installed.
112+
# jaz is a transparent shim that invokes `java` from PATH, adding crash-dump
113+
# capture and arg validation. Tomcat honors _RUNJAVA in place of $JRE_HOME/bin/java.
114+
# Set _RUNJAVA=/java/bin/java to bypass jaz.
115+
if [ -z "$_RUNJAVA" ] && command -v jaz >/dev/null 2>&1; then
116+
export _RUNJAVA="$(command -v jaz)"
117+
fi
109118

110119
# This needs to be set in order for catalina to read environmental properties
111120
export CATALINA_OPTS="$CATALINA_OPTS -Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.EnvironmentPropertySource"

0 commit comments

Comments
 (0)