How to optimise JMeter for performance tests
Tags: jmeter, performance, testing, bugs
Published: 2023-11-29 23:27:48

As is widely known, JMeter is a poorly optimized tool. This is due in part to the use of Virtual Threads. By comparison, golang (and the k6 tool that runs on it) uses goroutines, while the Kotlin language has coroutines.

Since JMeter is relatively old for a performance testing tool, several elements should be taken into account when creating and running test scenarios. We have divided them into two sections - scenario optimization (designing scenarios) and the JVM (running tests).

## JMeter script optimization

Before running the target test, make changes to the script to reduce RAM consumption on the server.

1. Use the latest version of Jmeter.
2. In testing, it is suggested to use `Regexp Variable Extractors` to extract data from the server response.
3. Assertions are used sensibly  - not everything must be included, only the most important elements of the response.
4. All listeners should be disabled, e.g. `View Results Tree` or `Summary Report` - they are too resource intensive.
5. All `Debug Samplers` should be disabled.
6. The best optimized language in JMeter is `Groovy`. If possible, it should be used instead of, for example, `Beanshell`.
7. If the tests include `Transaction Controller`, the `Generate Parent Sample` option should be unchecked.
8. When running the tests through `CLI` or Redline13, the `JVM` optimization configuration should be entered.

## JVM optimization

The next step is already optimizing the JVM itself, which runs under the JMeter "shell". It is not recommended to run tests from the UI due to the considerable RAM consumption - therefore, it is better to run scenarios from the console.

Someone might ask "What if I want to see the results on the fly?". We answer briefly: invest the time to set up tools locally to observe real time results. InfluxDB + Grafana can serve this purpose.

We run tests in the console along the lines of the following command.

```bash
java -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -Xms512m -Xmx747520m -d64 -jar C:\jmeter\bin\ApacheJMeter.jar -n -t scenario.jmx results.jtl -e -o results
```

The parameters inside the command are divided into two sections - JMeter parameters and JVMa parameters.

### JVMa parameters



```
-XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -Xms512m -Xmx747520m -d64
```

| Parameter               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| -XX:+UseConcMarkSweepGC | Forces the use of CMS garbage collector. This reduces overall throughput, but leads to much faster CPU time.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -XX:+DisableExplicitGC  | It prevents applications from forcing costly garbage collection and helps avoid unexpected interruptions.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| -Xms512m                | Minimum memory allocation pool for JVM marked in MB.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| -Xmx747520m             | The maximum memory allocation pool for the JVM denoted in MB. If we run the tests on an instance having 32GB, the tem parameter will take the value `-Xmx24576m` because we assume that 8GB will be allocated for other server processes. Therefore, we are left with 24GB which gives us 24576MB (since 1GB=1024MB)The maximum memory allocation pool for the JVM denoted in MB. If we run the tests on an instance having 32GB, the tem parameter will take the value `-Xmx24576m` because we assume that 8GB will be allocated for other server processes. Therefore, we are left with 24GB which gives us 24576MB (since 1GB=1024MB). |
| -d64                    | If you have a 64-bit operating system, use this parameter to explicitly tell the JVM to run in 64-bit mode.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

### JMeter parameters.

At this stage it is worth noting that we are not running either the `.bat` or `.sh` file. Instead, I use the `.jar` version - because we are running a java program.

```bash
-jar C:\jmeter\bin\ApacheJMeter.jar -n -t scenario.jmx -l results.jtl -e -o results
```

| Parameter                           | Description                                                                                              |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------- |
| -jar C:\jmeter\bin\ApacheJMeter.jar | Indication of JMeter implementation in `.jar` format.                                                    |
| -n                                  | This specifies JMeter is to run in cli mode.                                                             |
| -t scenario.jmx                     | Name of JMX file that contains the Test Plan.                                                            |
| -l results.jtl                      | Name of JTL file to log sample results to.                                                               |
| -e                                  | Generate report dashboard after load test.                                                               |
| -o results                          | Output folder where to generate the report dashboard after load test. Folder must not exist or be empty. |

With the tips above, running JMeter tests will be better optimized, and the team will avoid RAM problems. However, if the advice above fails, you may be left with nothing but [distributed testing](https://jmeter.apache.org/usermanual/jmeter_distributed_testing_step_by_step.html).