Note that there are some explanatory texts on larger screens.

plurals
  1. POjava imageio memory leak
    text
    copied!<p>I have two Java applications that both use a <em>ton</em> of memory, and both use ImageIO.write(). So far, that is the only thing I have found in common between the two.</p> <p>One resizes images in a loop. The other downloads images in a loop and saves them to disk. Here's the relevant code:</p> <p>1)</p> <pre><code>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); } </code></pre> <p>2) (inside a loop)</p> <pre><code>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); } </code></pre> <p>In both cases, the program uses a lot of memory. Right around a gig of RAM. And it doesn't get freed up when the loop is over. In both cases I have a swing gui running. When the image saving is all done and the gui is just idling, the program is still using sometimes 1Gb+ of memory. I have gone so far as to set every variable not directly used by the swing gui to <code>null</code> after the loop. To no effect.</p> <p>What am I missing?</p> <p>Thanks in advance for your help.</p> <p>More information: I just profiled application 1 in my IDE (Netbeans). I chose application one because it only deals with ImageIO (and not network IO), so it's a more controlled experiment.</p> <p>While the program was doing its thing (resizing images in a loop), the Total Memory hovered between roughly 900,000,000 ~ 1,000,000,000 bytes, while the Used Memory fluxuated between roughly 30% and 50% of the Total Memory being used at a given moment.</p> <p>And time spent in GC never went above 1%.</p> <p>As soon as the actual resizing was finished and the program went into "idle", two things happened: 1) The Total Memory stopped fluxuating and stayed static at 1,044,054,016 bytes, and 2) the Used Memory dropped to ~14,000,000 bytes (14 mb).</p> <p>So, it looks like the JVM is just not giving back memory space that it's no longer using.</p> <p>Agree? Or am I misreading this result?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload