What does JMeter's 'Reset bsh.Interpreter before each call' option cost you?
answer
- Look at the checkbox on every BeanShell element
- Ask what reset actually rebuilds
- It trades one resource for another
- The init file is involved when set
basics
~20 sTicking it throws away the element's interpreter and builds a new one on every invocation, re-sourcing the init file if one is configured. You pay construction per call, and the script loses any state it kept between calls.
solid answer
~40 sThe option is off by default. When it is on, `BeanShellTestElement.getBeanShellInterpreter()` calls `reset()` before binding the script variables, and `reset()` re-runs `init()` — it constructs a brand-new `bsh.Interpreter` and, if that element type's `beanshell.*.init` property is set, sources the file again. So it is a full rebuild per invocation on top of the interpretation you were already paying for. What you buy is that nothing accumulates in the namespace across a long run; JMeter's best-practices page suggests exactly this when a long test makes the interpreter use a lot of memory. What you lose is any variable or helper method the script relied on from a previous call.
code
xml · 6 lines<!-- hand-written GUI elements carry a qualified name -->
<boolProp name="BeanShellSampler.resetInterpreter">false</boolProp>
<boolProp name="BeanShellAssertion.resetInterpreter">false</boolProp>
<!-- the four TestBean elements use the bare name -->
<boolProp name="resetInterpreter">false</boolProp>go deeper
Know that every BeanShell element has a Reset bsh.Interpreter before each call control and that it is off by default. Do not tick it without a reason.
Explain that reset rebuilds the interpreter rather than clearing a namespace, and that the rebuild also re-sources the init file when one is configured for that element type.
Justify the trade in a real run: reach for it when a long test's interpreter memory grows, and refuse it when the injector's CPU is already the limit.
Decide whether an element that needs resetting to stay stable is worth keeping at all, rather than treating the checkbox as a permanent fix for a script that accumulates state.
## What the option actually does Every BeanShell element carries a **Reset bsh.Interpreter before each call** control. In the two elements with hand-written GUIs — the BeanShell Sampler and the BeanShell Assertion — it is a checkbox with that exact label. In the four TestBean elements (PreProcessor, PostProcessor, Timer, Listener) that string is the group heading and the checkbox itself reads **Reset Interpreter**. The effect is one branch at the top of `BeanShellTestElement.getBeanShellInterpreter()`: if the flag is set, `reset()` is called before the script variables are bound. `BeanShellInterpreter.reset()` is not a namespace clear — it re-runs `init()`, which does two things: - constructs a brand-new `bsh.Interpreter` and re-binds `log` on it; - if an init-file property is configured for that element, sources that file again. So the reset is a full teardown and rebuild, plus a re-read of the `.bshrc` if one is in play, and it happens on every single invocation rather than once per thread. ## The default, and where it lives in the .jmx The default is **off** — `resetInterpreter` is initialised to `false` in `BeanShellTestElement`, and the plan JMeter ships as a template writes it out as `false`. The property name is not uniform, which matters if you are grepping an inherited plan: | Element | Property in the `.jmx` | |---|---| | BeanShell Sampler | `BeanShellSampler.resetInterpreter` | | BeanShell Assertion | `BeanShellAssertion.resetInterpreter` | | PreProcessor, PostProcessor, Timer, Listener | `resetInterpreter` | ## What you buy and what you pay You buy a guarantee that nothing leaks forward. With the option off, one interpreter serves that element for the life of the thread, so anything the script defines — variables, methods, objects hung off the namespace — stays there until the run ends. JMeter's own best-practices page names the consequence: *"Some long-running tests may cause the interpreter to use lots of memory; if this is the case try using the reset option."* You pay interpreter construction on every call, on top of the interpretation you were already paying, and you lose the ability to carry state between iterations in the script's own namespace. If the script relies on a counter or a helper method defined in a previous call, ticking the box breaks it. ## When ticking it is the right call - A **soak-shaped** run where the same scripted element executes for hours and heap climbs with no other explanation. - A script that accumulates in its own namespace by design — building collections, holding parsed objects — where you would rather pay CPU than watch memory grow. - Never as a reflex on a plan whose injector is already the constraint: on a hot path this option makes an already-expensive element more expensive, not less.
- If an element has an init file configured, what does ticking the reset option do to it?It re-sources it on every call. `reset()` calls `init()`, and `init()` sources the file named by that element's `beanshell.*.init` property whenever it builds an interpreter. With reset off the file is sourced once per element per thread; with reset on it is sourced once per invocation, which is usually the more expensive half of the change.
- Would you tick this option on a plan whose injector is already the constraint?No. On a hot path it makes an expensive element more expensive: you add interpreter construction to interpretation on every sample. It is a remedy for interpreter memory growth in a long run, not a performance option. If the injector is short of CPU, the fix is to remove or replace the element, not to reset it more often.
saying these in an interview costs you the question
- Calling the reset option a performance optimisation
- Assuming reset only clears variables rather than rebuilding the interpreter
- Thinking the option defaults to on
- Forgetting that reset re-sources the configured init file
- Expecting script state to survive across calls with reset ticked