Fix memory leak for Transaction Controller using parent samples #6386
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Follow issue in this issue
Basically, there's a memory leak, specifically when transactions are set as a parent. All the sub results maintains their data until the end of the thread, which can build up significantly, especially when there are large (uncompressed) responses
This PR fixes this, and improves the memory usage of JMeter by a lot, even without using transactions. Because we're cleaning all the SamplerResult data after it's sent to all the listeners. There is no reason to maintain the sampler data for that specific thread. It now clears all fields with large data and removes the parent reference, so GC can actually clear it.
Motivation and Context
JMeter is very memory intensive and by far the majority of the memory is used for processed samplers, just holding memory until the end of the thread run.
How Has This Been Tested?
I've done a lot of testing, made fixes and looks like it is working out well and preserving all the sampleresults/httpsamplerresults to all the listeners.
I've made a couple of scripts to test with a lot of transactions, with and without parent usage. Some synthetic scripts with a lot of 1MB json requests
Screenshots (if appropriate):
This is a graph of original 5.6.3 version, with 30 transactions, using parents, and a single 1MB.json file in it. Running 30 threads and 1 second think time between the transaction (meaning a thread runs 30 seconds + response times)
Then ran the exact same jmx against this fix:
Memory is a LOT lower.Also ran the same tests without the usage of transaction as a parent:
5.6.3 baseline:
This fix:
Without the fix, we can see actual heap usage is hovering between 150MB and 200MB, with a max heap 420MB. With the fix, it is hovering between 50MB and 100MB with a max heap of 247MB. Also much more stable.
I've done some aggressive manual full GCs to see the real usage, and after the fix, the low end was significantly lower.
Here's a run against a realistic real website, 5 pages (transactions) with parent=true:
5.6.3 baseline:
After the fix:
Types of changes
It creates a deep copy of the sampler result and then forwards that to the listeners. After that we can safely remove all the values from the sampler.
It now only clears data after a root sampler is done, because if it's not on the root and generateParent is enabled, subresults keep building up.
Checklist: