Bug 47921

Summary: Variables not released for GC after JMeterThread exits.
Product: JMeter - Now in Github Reporter: Ronan Klyne <ronan.klyne>
Component: MainAssignee: JMeter issues mailing list <issues>
Status: RESOLVED FIXED    
Severity: normal CC: p.mouawad
Priority: P2    
Version: 2.5   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: Fixes the leaks
Test Plan as explained
New fix

Description Ronan Klyne 2009-09-30 08:19:14 UTC
If a test plan stores data in JMeter variables, then the data is not released until the test plan terminates.
This data should be released when the thread group terminates.

To reproduce,
 * Create two thread groups with the same number of threads and a BSF sampler under each one.
 * Add some code to each BSF sampler to create some multi Mb string data and store it in vars.
 * Set the test plan option "Run thread groups sequentially".
 * Run the test.

Observe that the memory used by JMeter goes up when running the first thread group, and up again by the same amount during the second thread group. Memory is not released until the end of the test plan.

Please see this mail for the reasoning leading up to this:
http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200909.mbox/%3C4AC1AC85.2010805@groupbc.com%3E
Comment 1 Philippe Mouawad 2011-09-14 21:34:38 UTC
Created attachment 27497 [details]
Fixes the leaks

Hello,
I tracked references and I saw 2 remaining issues:
- JMeterThread holds a reference to JMeterVariables through threadVars, at end of thread this one holds data that were added by Samplers . So what I did was to take an image of threadVars at start in a variable called threadVars and then at end of thread, clean all keys that were not here at start , DO YOU SEE ANY CASE THAT WOULD INTRODUCE AN ISSUE ?
- JMeterContext hold a reference to JMeterThread in thread variable which is not reset to null, as this is repositionned in initRun at each run, I can remove if safely I think


Regards
Philippe
Comment 2 Philippe Mouawad 2011-09-14 21:35:50 UTC
Created attachment 27498 [details]
Test Plan as explained
Comment 3 Sebb 2011-09-14 23:26:39 UTC
Not sure I agree with the change to JMeterContext - the clear() method may be called other than at the end.

I'm not sure why one needs to keep any JMeterVariables at the end of the JMeterThread run - the JMeterThread instance is not re-used - so I would have though it would be OK to clear all the variables. But really I would expect the JMeter Thread to be released at the end of its run, so probably no point even clearing the variables. However that does not seem to be the case.

Seems to me the proper fix would be to ensure that the JMeterThread is released on exit, but I don't know what is retaining the reference.

Note that the Debug Samplers copy the contents of the variables into their sample results, which are stored by the Tree View Listener.
Comment 4 Philippe Mouawad 2011-09-15 09:29:24 UTC
Hello Sebb,
I tracked and JMeterThread is finally retained by TestCompiler#pairing which is static and never cleaned once JMeterThread ends.

In details:
1) pairing holds a reference to TestCompiler$ObjectPair
2) TestCompiler$ObjectPair holds a reference through child to BSFSampler 
3) BSFSampler holds a reference through threadContext to JMeterThread

Reading code I don't fully understand the use of pairing.
Regards
Philippe
Comment 5 Philippe Mouawad 2011-09-15 10:01:26 UTC
Again,
And there is another reference held through IterationListener (instance class).

TestCompiler$ObjectPair>ThreadGroup#propMap>TestElementProperty#savedValue and value>LoopController#iterationListeners.


Regards
Philippe
Comment 6 Philippe Mouawad 2011-09-15 10:07:53 UTC
Created attachment 27499 [details]
New fix

Hello Sebb,
Here is another solution that:
- unregister listener
- nullifies thread reference in clear0

By the way I don't see other calls to clear except JMeterThread#run.


Regards
Philippe
Comment 7 Philippe Mouawad 2011-09-17 07:49:26 UTC
Hello Sebb,
Did you have time to look at this one ?
Are there still issues in it ?
Thank you
Regards
Comment 8 Sebb 2011-09-17 10:55:21 UTC
Thanks for the new patch.

There was one raw type, and I localised the iterationListener variable to the run method.

URL: http://svn.apache.org/viewvc?rev=1171944&view=rev
Log:
Bug 47921 - Variables not released for GC after JMeterThread exits.

Modified:
   jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/Controller.java
   jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/GenericController.java
   jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
   jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java
   jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
   jakarta/jmeter/trunk/xdocs/changes.xml

Not sure if this is yet enough to fix all the retained objects.
Comment 9 Sebb 2011-09-17 21:51:14 UTC
Hopefully this is now fixed.

If not, please re-open with details.
Comment 10 The ASF infrastructure team 2022-09-24 20:37:44 UTC
This issue has been migrated to GitHub: https://github.com/apache/jmeter/issues/2290