JDK-6798062 : Memory Leak on using getFiles of FileSystemView
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u10
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp,windows_vista
  • CPU: x86
  • Submitted: 2009-01-27
  • Updated: 2011-01-19
  • Resolved: 2009-12-28
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 6 JDK 7
6u18Fixed 7 b55Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
tested on jre 1.6_10

ADDITIONAL OS VERSION INFORMATION :
Windows Vista 64Bit business..

though problem seems to appear on more os

A DESCRIPTION OF THE PROBLEM :
On using FileSystemView.getFiles()  to retrieve all  children of a directory  the used memory shown by the OS rises. Though Heap and non Heap memory shown by jconsole   stay the same.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
SSCCE given below ... just run it



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Simple demo should just print ount current  ammount of files on the disc...
And not use much memory.
ACTUAL -
Memory usage of the java process rose by about 200 MiB  per minute.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import java.io.File;
import javax.swing.filechooser.FileSystemView;


public class LeakTest {

	private static long counter = 0;
	
	private static FileSystemView view = FileSystemView.getFileSystemView();

	public static void main(String[] args) throws InterruptedException  {
		
		while (true) {
			for (File f : File.listRoots()) {
				if (f.isDirectory()) {
					countFiles(f);
					System.out.println("found: "+counter);
				}
			}
			System.out.println("found Total: "+counter);
			counter = 0;
			Thread.sleep(1000);
		}
		
		

	}
	
	private static void countFiles(File root) {
		
		for (File f :view.getFiles(root, false)) {
			if (f.isDirectory()) {
				countFiles(f);
			} else {
				counter++;
			}
		}
	}

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Not a very good one:
Using the following method gives nearly the same behaviour... though FileSystemViews list files still shows different kind of files as visible then File.isHidden()
i.e. $Recycle.bin  on Windows

private static File[] getFiles(File parent,boolean useHidden) {
		File[] files = parent.listFiles();
		if (files == null) return new File[0];
			
		if (useHidden) {
			int length = files.length;
			for (int i = 0; i < length; i++) {
				if (files[i].isHidden()) {
					length--;
					System.arraycopy(files, i+1, files, i,  length-i );
				}
			}
			if (length != files.length) {
				File[] onlyVisible = new File[length];
				System.arraycopy(files, 0, onlyVisible, 0, length);
				return onlyVisible;
			}
		}
		return files;
		
	}

Comments
EVALUATION Windows native code contains memory leaks. It invokes the ShellFolder.GetDisplayNameOf method without release memory. Documentation about the GetDisplayNameOf method available here: http://msdn.microsoft.com/en-us/library/bb775071(VS.85).aspx
25-03-2009

EVALUATION This is something we need to look at. Upgraded to P2, assigned to the JFileChooser team
02-02-2009