An Apache JMeter run is started with JVM_ARGS="-Xmx4g" and HEAP left unset. What heap does the JVM get?
answer
- Two -Xmx flags on one line
- Order decides, nothing is removed
- Only what you repeat is superseded
- The initial size is left behind
basics
~10 sMaximum 4 GB, initial still 1 GB. The launcher expands HEAP's default first and appends JVM_ARGS afterwards, so the later -Xmx4g wins while -Xms1g and -XX:MaxMetaspaceSize=256m stay on the line untouched.
solid answer
~40 s`bin/jmeter` builds `ARGS` from `HEAP` and its siblings, then runs `java $ARGS $JVM_ARGS $JMETER_OPTS -jar ApacheJMeter.jar`. With `HEAP` unset the script still supplies `-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m`, and `-Xmx4g` from `JVM_ARGS` lands after it. The JVM honours the last `-Xmx`, so the maximum becomes 4 GB — but nothing was removed, so the initial heap is still 1 GB and the metaspace cap is still 256 MB. The manual's phrase that `JVM_ARGS` "will override the HEAP settings in the script" is true positionally, not substitutionally: it supersedes flags you repeat and leaves the rest alone. To move a whole injector past the shipped gigabyte, set the entire `HEAP` string instead of patching one flag.
code
bash · 11 lines$ JVM_ARGS="-Xmx4g" jmeter -n -t plan.jmx -l results.jtl
# bin/jmeter assembles, in this order:
# ARGS="$JAVA_OPTS $SERVER $DUMP $HEAP $VERBOSE_GC $GC_ALGO ..."
# "$JAVA_HOME/bin/java" $ARGS $JVM_ARGS $JMETER_OPTS -jar ApacheJMeter.jar "$@"
#
# effective line: ... -Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m ... -Xmx4g ...
# effective heap: initial 1g, maximum 4g, metaspace cap 256m
# Change the whole string instead, when you mean to change the heap:
$ export HEAP="-Xms4g -Xmx4g -XX:MaxMetaspaceSize=256m"go deeper
Recall that JMeter has two ways in: HEAP for the memory string and JVM_ARGS for extra java options. Knowing both variables exist and that JVM_ARGS comes last is enough at this level.
Explain the assembly order in bin/jmeter and why a repeated flag supersedes rather than replaces. Say explicitly which flags survive untouched: -Xms and the metaspace cap.
Show the operational consequence: a fleet patched with -Xmx alone runs with a mismatched initial and maximum heap. Verify with the Max memory line in jmeter.log rather than trusting the command you typed.
Set the rule about which seam carries which kind of change: HEAP in setenv.sh for durable machine configuration, JVM_ARGS for one-off experiments and -D properties, and never a half-override that leaves the pair inconsistent.
## What the launcher actually assembles `bin/jmeter` in Apache JMeter 6.0.0 builds one string of JVM options and then appends the user's own: ```sh ARGS="$JAVA_OPTS $SERVER $DUMP $HEAP $VERBOSE_GC $GC_ALGO $SYSTEM_PROPS $JMETER_LANGUAGE $RUN_IN_DOCKER" "$JAVA_HOME/bin/java" $ARGS $JVM_ARGS $JMETER_OPTS -jar "$PRGDIR/ApacheJMeter.jar" "$@" ``` `HEAP` is expanded **inside** `ARGS`; `JVM_ARGS` comes **after** it. With `HEAP` left unset the script supplies its default, so the effective command line for `JVM_ARGS="-Xmx4g"` contains: ``` ... -Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m ... -Xmx4g ... ``` The JVM takes the last occurrence of a repeated `-Xmx`, so the maximum heap is **4 GB**. Nothing removed the earlier flags: `-Xms` is still `1g` and the metaspace cap is still `256m`. ## Why the manual calls that an override The Getting Started page says `JVM_ARGS` "will override most pre-defined settings" and that `JVM_ARGS="-Xms1024m -Xmx1024m" jmeter -t test.jmx` "will override the HEAP settings in the script". Read that precisely — the override is **positional, not substitutional**: - A flag you repeat in `JVM_ARGS` supersedes the one `HEAP` put on the line. - A flag you do **not** repeat is left exactly as `HEAP` set it. - Nothing warns you about the duplicate; the run starts normally. ## What that asymmetry costs An injector raised past its shipped gigabyte with only `-Xmx4g` starts at `-Xms1g` and grows toward `-Xmx4g`. JMeter ships `-Xms` and `-Xmx` equal for a reason and its own `setenv.sh` example keeps them equal (`export HEAP="-Xms1G -Xmx1G -XX:MaxMetaspaceSize=192m"`); a half-override quietly breaks that pairing. If you intend to change the heap rather than patch one flag, set the whole `HEAP` string: ```sh export HEAP="-Xms4g -Xmx4g -XX:MaxMetaspaceSize=256m" ``` ## Where each mechanism belongs | Mechanism | Scope | Use it when | |---|---|---| | `HEAP` in `bin/setenv.sh` | every run on that install | the machine is a dedicated injector | | `HEAP` exported for one command | that invocation | a one-off larger run | | `JVM_ARGS` on the command line | that invocation | adding `-D` properties, or patching a single JVM flag | | `JMETER_COMPLETE_ARGS` | that invocation | you want to supply the *entire* JVM line yourself | ## Verifying rather than assuming Two checks settle it without guessing: 1. Read `jmeter.log`. `org.apache.jmeter.JMeter` logs `Max memory =` at startup with `Runtime.getRuntime().maxMemory()` in bytes — about `4294967296` for four gigabytes. 2. Inspect the process arguments on the injector and count how many `-Xmx` flags are there. Seeing two is normal for this launcher, not a bug. The same layering applies on Windows: `bin/jmeter.bat` builds `ARGS` from `%HEAP%` and friends and then runs `"%JM_LAUNCH%" %ARGS% %JVM_ARGS% -jar ...`, so `JVM_ARGS` is appended last there too.
- How would you prove which maximum heap the run actually used?Read `jmeter.log`. The startup block logged by `org.apache.jmeter.JMeter` includes `Max memory =` with `Runtime.getRuntime().maxMemory()` in bytes: about 4294967296 for four gigabytes, about 1073741824 if the override never took effect. Inspecting the running process's arguments works too, and seeing two `-Xmx` flags there is normal for this launcher.
- Does the same ordering hold on Windows?Yes. `bin/jmeter.bat` builds `ARGS` from `%HEAP%`, `%GC_ALGO%` and the rest, then runs `"%JM_LAUNCH%" %ARGS% %JVM_ARGS% -jar "%JMETER_BIN%ApacheJMeter.jar"`. `JVM_ARGS` is appended last there as well, so a repeated flag in it supersedes the launcher's own in exactly the same way.
Like a checklist where a later entry crosses out an earlier one: the launcher writes -Xmx1g first and your -Xmx4g after it, and the reader acts on the last line rather than on the whole page.
saying these in an interview costs you the question
- Says JVM_ARGS replaces the whole HEAP string
- Expects a duplicate -Xmx to fail the run
- Assumes the initial heap follows the new maximum
- Puts JVM_ARGS before ARGS in the command line
- Thinks the metaspace cap scales with -Xmx