JDK-8160053 : Memory leak with indeterminate ProgressBar and ProgressIndicator
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8u92,9
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: other
  • CPU: x86
  • Submitted: 2016-06-19
  • Updated: 2016-07-07
  • Resolved: 2016-07-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Blocks :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10586]

A DESCRIPTION OF THE PROBLEM :
Memory usage keeps increasing when there's a indeterminate ProgressBar or ProgressIndicator on scene. The moment the progressBar or ProgressIndicator is removed or set to a determinate value, the memory stops increasing.

Note: At some point ( Usually at 40MB ) the memory usage will go back to normal, but it will again keep increasing until it reaches this point again.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Create a JavaFX ProgressBar or ProgressIndicator
2) Set it to be indeterminate by calling "progress.setProgress(-1);"
3) Add it to the Scene, add the Scene to the Stage and display the Stage.
4) Monitor memory usage

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
For a basic application the beginning memory usage will be at 10MB. Once the ProgressBar or ProgressIndicator is set to indeterminate, it'll start rising at a pace of about 0.5MB per second. Once it reaches the point of about 40-45MB, it'll go back to normal, but continue to rise.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package xyz.spajk.java.memleak;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ProgressLeak extends Application 
{
	// If set to true, RAM will be output to GUI instead of console
	public static boolean outputGUI = true;
	
	public static void main(String[] args)
	{
		launch(args);
	}
	
	@Override
	public void start(Stage primaryStage) throws Exception 
	{
		primaryStage.setTitle("ProgressBar memory leak");
		
		VBox root = new VBox();
		root.setAlignment(Pos.CENTER);
		root.setSpacing(10);
		
		ProgressBar progress = new ProgressBar();
		progress.setProgress(-1);
		
		Button changeButton = new Button("Change");
		changeButton.setOnAction(new EventHandler<ActionEvent>() {
		    @Override public void handle(ActionEvent e) {
		        if(progress.isIndeterminate())
		        {
		        	progress.setProgress(0.5);
		        }
		        else
		        {
		        	progress.setProgress(-1);
		        }
		    }
		});
		
		root.getChildren().addAll(progress, changeButton);
		
		Scene scene = new Scene(root, 710, 400);
		primaryStage.setScene(scene);
        
		primaryStage.show();
		
		Thread rammonitor = new Thread() {
			@Override
            public void run() {
				Runtime rt = Runtime.getRuntime();
				long usedKB = (rt.totalMemory() - rt.freeMemory()) / 1024;
				
            	System.out.println("Ram usage: " + usedKB);
            	
            	try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

            	run();
            }
		};
		rammonitor.start();
	}
}

---------- END SOURCE ----------


Comments
Now that I have resolved JDK-8151165 I have returned to this issue. What I see is that the typical pattern occurs of a growing heap that is then GC'd before growing again. This is a typical pattern in JavaFX and occurs in (I would presume) the graphics / scenegraph layer of the code. Whilst the indeterminate progress indicator does lead to the heap growing faster, this is a function of the animation that is occurring. The key point is that there is no memory leak, only memory usage that is then fully GC'd and returned to being free memory. A memory leak would imply that it would not be available for GC.
07-07-2016

Yep - almost certainly a duplicate of one of the issues linked from JDK-8090322, but because of the test case I will leave this issue open until JDK-8090322 is resolved, and then test before / after using this test case to ensure things are fixed.
26-06-2016

This is likely another bug that needs the fix for JDK-8090322 before it can be fully fixed.
25-06-2016