Terminating Performance Tests and Generating Reports Using JVM Stop Flags and Arthas
The article explains how to safely stop ongoing performance tests without losing data by using JVM termination flags, Arthas to modify static variables or invoke stop(), and provides sample Java code for implementing a graceful termination interface that still records results for reporting.
During regular performance testing, it is sometimes impossible to accurately estimate the performance metrics of the target interface or method, so testers rely on repeated stress‑test parameters; when the test duration or iteration count becomes excessive or the test goal is already reached, the test must be stopped without losing the collected data, requiring continued recording and aggregation of results to produce a final report.
Because the JVM process cannot be terminated directly during a stress‑testing service, a termination flag is used to end the test early, which leads to the topic of stopping performance tests and outputting reports.
The approach follows the timed and quantitative stress‑testing mode described in a video tutorial, where a specific key is used to control termination.
In local stress testing, the tool Arthas can modify static variables in the JVM or invoke the stop() method; a detailed implementation is shown in the linked video. While this works during service runtime, a cleaner solution is to expose an external termination API that calls stop() directly.
Stopping the test does not affect subsequent data collection or statistical analysis. The full source code is available in the open‑source repository (access via git), and a representative snippet of the quantitative virtual class is provided below.
@Override
public void run() {
try {
before();
List<Long> t = new ArrayList<>();
long ss = Time.getTimeStamp();
for (int i = 0; i < times; i++) {
try {
threadmark = mark == null ? EMPTY : this.mark.mark(this);
long s = Time.getTimeStamp();
doing();
long e = Time.getTimeStamp();
excuteNum++;
long diff = e - s;
t.add(diff);
if (diff > HttpClientConstant.MAX_ACCEPT_TIME) marks.add(diff + CONNECTOR + threadmark);
if (status() || key) break;
} catch (Exception e) {
logger.warn("执行任务失败!", e);
logger.warn("执行失败对象的标记:{}", threadmark);
errorNum++;
}
}
long ee = Time.getTimeStamp();
logger.info("执行次数:{},错误次数: {},总耗时:{} s", times, errorNum, (ee - ss) / 1000 + 1);
Concurrent.allTimes.addAll(t);
Concurrent.requestMark.addAll(marks);
} catch (Exception e) {
logger.warn("执行任务失败!", e);
} finally {
after();
}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
