Skip to content

build(docker): install jemalloc + mimalloc; default LD_PRELOAD to jemalloc#35410

Open
wezell wants to merge 1 commit intomainfrom
issue-32320-jemalloc-is-back
Open

build(docker): install jemalloc + mimalloc; default LD_PRELOAD to jemalloc#35410
wezell wants to merge 1 commit intomainfrom
issue-32320-jemalloc-is-back

Conversation

@wezell
Copy link
Copy Markdown
Member

@wezell wezell commented Apr 21, 2026

Installing this for jemalloc's profiling - we can see what is eating off-heap mem when an oom is issued

Summary

  • 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.

is jemaloc better than minaloc

⏺ No, not 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

🤖 Generated with Claude Code

…D to jemalloc

Install both libjemalloc2 and libmimalloc2.0 in the runtime and dev-env images,
and switch the default LD_PRELOAD in setenv.sh to libjemalloc.so.2. LD_PRELOAD
remains overridable at runtime, so operators can still swap back to mimalloc
via env var without an image change.

Ref: #32320

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 21, 2026

Claude finished @wezell's task in 1m 15s —— View job


Review

  • Read changed files
  • Analyze for issues

1. Backtick syntax — setenv.sh:109

export LD_PRELOAD=${LD_PRELOAD:-"/usr/lib/`uname -m`-linux-gnu/libjemalloc.so.2"}

The file opens with #!/bin/sh and already uses $() for the same pattern at line 6 (-Djava.library.path=/usr/lib/$( uname -m )-linux-gnu/). Backtick substitution works but is inconsistent. Fix this →

2. Duplicate libarchive-toolsdocker/dev-env/Dockerfile:37-39

apt-get install -y --no-install-recommends bash zip unzip wget libtcnative-1\
tzdata tini ca-certificates openssl libapr1 libpq-dev curl gnupg\
vim libarchive-tools postgresql-common libmimalloc2.0 libjemalloc2 libarchive-tools

libarchive-tools appears twice on the same install line. Harmless but sloppy — the second occurrence should be removed. Fix this →

3. Silent failure if path doesn't resolve — setenv.sh:109

If libjemalloc.so.2 isn't present at the computed path (e.g., a base image change), the JVM will refuse to start with ERROR: ld.so: object 'libjemalloc.so.2' from LD_PRELOAD cannot be preloaded. No guard in place. Low risk since both Dockerfiles install the package and uname -m correctly maps to the GNU triplet, but the failure mode is opaque. A startup-time [ -f "$_jemalloc_path" ] check with a fallback and warning would make this more operator-friendly.

4. Upgrade path for existing deployments with LD_PRELOAD pinned to mimalloc

Operators who pinned LD_PRELOAD=.../libmimalloc.so.2 in their environment will not pick up jemalloc automatically — which is the documented intent. Worth a one-liner in the release notes so they know they're still on mimalloc after upgrading, not on jemalloc as the new default implies.


Issues 1 and 2 are clean fixes. Issues 3 and 4 are judgment calls, not blockers.

@wezell wezell requested a review from yolabingo April 21, 2026 23:30
@wezell wezell requested a review from swicken April 21, 2026 23:33
@wezell wezell enabled auto-merge April 21, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : Backend PR changes Java/Maven backend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant