I have two Java applications that use a ton of memory, and both use ImageIO.write (). So far, this is the only thing I have found between them.
One resizes images in a loop. Another loads the images in a loop and saves them to disk. Here is the relevant code:
one)
for(File imageFile : imageFilesList) { if(!stillRunning) return; File outputFile = new File(imageFile.getAbsolutePath().replace(sourceBaseFolder.getAbsolutePath(), destinationFolder.getAbsolutePath())); try { outputFile.mkdirs(); BufferedImage inputImage = ImageIO.read(imageFile); BufferedImage resizedImage = ImageResizer.resizeImage(inputImage, maxHeight, maxWidth); ImageIO.write(resizedImage, "jpg", outputFile); } catch(IOException ex) { userInterface.displayMessageToUser("IOException ocurred while converting an image: " + ex.getLocalizedMessage()); System.out.println(outputFile.getAbsolutePath()); ex.printStackTrace(); return; } imagesConverted++; userInterface.updateTotalConvertedImages(++convertedFiles); }
2) (inside the loop)
try { u = new URL(urlString); uc = u.openConnection(); uc.addRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"); uc.connect(); uc.getInputStream(); in = uc.getInputStream(); BufferedImage tempImage = ImageIO.read(in); String fileName = fn = ImageDownload.getFileName(u.getPath()); fileName = outputDirString + FILE_SEPARATOR + fileName; while (new File(fileName).exists()) { fileName = appendCopyIndicator(fileName); } ImageIO.write(tempImage, "jpg", new File(fileName)); parent.notifyOfSuccessfulDownload(fn); in.close(); } catch (FileNotFoundException ex) { parent.notifyOfFailedDownload(fn); } catch (IOException ex) { parent.handleException(ex); }
In both cases, the program uses a lot of memory. Right around the ram concert. And he is not released when the cycle is completed. In both cases, swing gui works for me. When image saving is completed, and gui is just idle, the program still sometimes uses 1 Gb + memory. I got to the point that every variable not used directly by swing gui, is null
after the loop. No effect.
What am I missing?
Thanks in advance for your help.
Additional Information: I just profile application 1 in my IDE (Netbeans). I chose the application alone because it only deals with ImageIO (and not the IO network), so this is a more controlled experiment.
While the program was doing its job (resizing images in a loop), Total Memory was between about 900,000,000 ~ 1,000,000,000 bytes, while used memory was reduced from about 30% to 50% of the total memory used for a given moment.
And the time spent at GC never exceeded 1%.
As soon as the actual resizing ended and the program turned to βidleβ, two things happened: 1) Total Memory stopped fluxing and remained static at 1,044,054,016 bytes and 2) Used memory dropped to ~ 14,000,000 bytes (14 mb )
So, it looks like the JVM just doesn't return the memory space that it no longer uses.
I agree? Or am I reading this result incorrectly?