skip to content

Each JMeter injector in your team has bin/jmeter hand-edited to raise the heap. How would you get that under control?

level: principalimportance: should knowfreq 34%

answer

  1. The distribution owns that file
  2. One seam is upgrade-safe
  3. Sourced before any default is applied
  4. Change the whole string, not one flag

basics

~10 s

Move the setting into bin/setenv.sh, which bin/jmeter sources before applying its own defaults and which an upgrade cannot overwrite. Set the whole HEAP string per machine class, and forbid edits to the shipped launcher.

solid answer

~40 s

Editing `bin/jmeter` puts the decision in a file the distribution owns: an upgrade replaces it, the change leaves no record, and two generators drift apart invisibly. The script's own header says so — "Do not set the variables in this script. Instead put them into a script `setenv.sh` in `JMETER_HOME/bin`". `bin/jmeter` sources `setenv.sh` before computing any default, so an `export HEAP=...` there is both persistent and upgrade-safe. Set the full string, not one flag: `-Xms` and `-Xmx` ship equal, and patching only `-Xmx` through `JVM_ARGS` leaves `-Xms1g` behind. Keep `GC_ALGO` and the unconditional `-XX:+HeapDumpOnOutOfMemoryError` unless you have a measured reason, treat `JMETER_COMPLETE_ARGS` as a last resort because it drops all of them, and archive `jmeter.log` so the `Max memory` line makes each run auditable.

go deeper

for a junior

Recall the rule the launcher itself states: customisations go in bin/setenv.sh, not into bin/jmeter. That alone avoids losing the setting at the next upgrade.

for a middle

Explain why setenv.sh wins mechanically — it is sourced before the HEAP default is computed — and why a JVM_ARGS override changes only the flags it repeats.

for a senior

Show how you would find the drift you already have: compare the Max memory line across injectors' jmeter.log files rather than trusting what each machine's launcher looks like.

for a principal

Own the whole policy: one documented HEAP per machine class, the shipped GC_ALGO and heap-dump flags left alone without evidence, JMETER_COMPLETE_ARGS reserved for a wrapper that supplies everything, and the value recorded per run.

## Why the hand-edit is the actual problem Every Apache JMeter injector needs the same decision expressed once: what `HEAP` should be on that class of machine. Editing `bin/jmeter` on each box expresses it in the worst available place. The file is part of the distribution, so an upgrade replaces it and the setting vanishes with no error; there is no record of who changed what; and two generators can drift apart while both look identical from the outside. The script's header says so itself: "Do not set the variables in this script. Instead put them into a script `setenv.sh` in `JMETER_HOME/bin` to keep your customizations separate." ## The seams the launcher already gives you | Seam | Lifetime | What it costs | |---|---|---| | `bin/setenv.sh` (`setenv.bat`) | every run on that install | you must create and distribute one file per install | | `HEAP`/`GC_ALGO` exported by the caller | one invocation | the value lives in whatever launched JMeter | | `JVM_ARGS` on the command line | one invocation | patches single flags; leaves the rest of `HEAP` in place | | `JMETER_COMPLETE_ARGS` | one invocation | you own the entire JVM line, including the flags the launcher sets for you | `bin/jmeter` sources `setenv.sh` before it computes any default, so it is the only seam that is both persistent and upgrade-safe. That is the default answer for a fleet of dedicated injectors. ## The judgment calls 1. **Set the whole `HEAP` string, not one flag.** `-Xms` and `-Xmx` ship equal at `1g`, and the manual's own `setenv.sh` example keeps them equal. Raising a generator with `JVM_ARGS="-Xmx8g"` alone leaves `-Xms1g` behind, because `JVM_ARGS` is appended after `ARGS` and overrides only what it repeats. 2. **Decide whether one value fits every generator.** `HEAP` is a fixed string applied verbatim: the launcher does no sizing of its own and never adapts the number to the box it is on. So the value has to be valid on the smallest generator in the class — either standardise the machine class alongside the string, or have `setenv.sh` compute the number on the machine. 3. **Treat `JMETER_COMPLETE_ARGS` as a last resort.** It gives total control and takes away `HEAP`, `GC_ALGO`, `-server`, `-Djava.security.egd=file:/dev/urandom`, the `--add-opens` block and `-XX:+HeapDumpOnOutOfMemoryError` in one move. Note that `bin/jmeter.sh` sets it, so "we standardised on `jmeter.sh`" is the same decision made by accident. 4. **Keep `-XX:+HeapDumpOnOutOfMemoryError` whatever you choose.** The launcher's own comment is "does not cost anything unless triggered", and it is the difference between an exhausted injector you can diagnose and one you cannot. 5. **Make the value auditable.** `jmeter.log` records `Max memory =` in bytes at startup; archiving that log per run turns "which heap did this generator have" into a lookup instead of an argument. ## Where to stop This is a decision about the launcher, and it is worth separating from the two questions it usually arrives attached to: how big an injector the workload needs at all, and what inside the plan is holding the objects. Standardising `HEAP` makes the setting reproducible and diffable; it does not make an oversized number correct. The strongest version of the answer sets one documented `HEAP` per machine class in `setenv.sh`, forbids edits to `bin/jmeter`, leaves `GC_ALGO` and `DUMP` at their shipped values unless there is a measured reason, and treats a per-run `JVM_ARGS` as an experiment rather than a configuration.

  • What breaks if one machine class has less RAM than the standard HEAP string asks for?
    Nothing in the launcher notices. `HEAP` is expanded verbatim onto the `java` line — `bin/jmeter` does no sizing and never adapts the number to the machine — so the failure, if any, is the JVM's at start-up, before any sampling. Standardise the machine class alongside the string, or have `setenv.sh` compute the number on the box.
  • Someone proposes standardising on bin/jmeter.sh for consistency. What do you tell them?
    That it makes the opposite decision by accident. `bin/jmeter.sh` exports `JMETER_COMPLETE_ARGS=true`, which makes `bin/jmeter` empty its whole option block, so `HEAP`, `GC_ALGO`, `-server` and `-XX:+HeapDumpOnOutOfMemoryError` are all dropped and the JVM's own defaults apply.
  • How would you make the heap each run used auditable after the fact?
    Archive `jmeter.log` with the results. `org.apache.jmeter.JMeter` logs a startup block containing `java.version=`, `java.vm.name=` and `Max memory =` in bytes, so the heap a given run actually received becomes a lookup rather than a reconstruction from whichever launcher happened to be on that machine.

saying these in an interview costs you the question

  • Keeps the edit in bin/jmeter and documents it instead
  • Raises only -Xmx and leaves -Xms at one gigabyte
  • Standardises on bin/jmeter.sh for consistency
  • Drops the OOM heap dump while taking full control
  • Sets one heap value for unlike machine classes