title: Memory leak in java ImageIO.read()
body: <p>I am utilizing ImageIO.read(). The class which is called by the main method of the original App is this:</p>
  
  <pre><code>import java.awt.*;
  import javax.swing.*;
  import java.io.File;
  import java.awt.image.BufferedImage;
  import java.awt.event.*;
  import javax.swing.JPanel;
  
  class ImageGenerator extends JPanel{
  
  JpegReader jpeg;
  
  public ImageGenerator(Aplicacion a){
      jpeg = new JpegReader();
      loadImage();
  
  }
  
  
  private void loadImage(){
      String path = "C:\\image.jpg";
      image = new BufferedImage(100,100, BufferedImage.TYPE_INT_RGB); //in case error
      try{
          image = jpeg.readImage(new File(path));
      }catch(Exception e){
          System.err.println(e.getMessage());
      }
  }
  public void paint(Graphics g){
  
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
              RenderingHints.VALUE_INTERPOLATION_BICUBIC);
      g2.drawImage(image, 0, 0, 1000, 800, null);
  }
  
  }
  </code></pre>
  
  <p>I am using the above in conjunction with this other class JpegReader, which I actually found on StackOverflow as an answer, but I forgot the name of the author to quote him.</p>
  
  <pre><code>import java.awt.image.BufferedImage;
  import javax.imageio.*;
  import javax.imageio.stream.ImageInputStream;
  import java.awt.color.*;
  import java.awt.image.*;
  import java.io.File;
  import java.io.IOException;
  import java.util.Iterator;
  import java.util.ArrayList;
  import org.apache.sanselan.Sanselan;
  import org.apache.sanselan.common.byteSources.ByteSource;
  import org.apache.sanselan.common.byteSources.ByteSourceFile;
  import org.apache.sanselan.ImageReadException;
  import org.apache.sanselan.formats.jpeg.JpegImageParser;
  import org.apache.sanselan.formats.jpeg.segments.UnknownSegment;
  public class JpegReader {
  
  public static final int COLOR_TYPE_RGB = 1;
  public static final int COLOR_TYPE_CMYK = 2;
  public static final int COLOR_TYPE_YCCK = 3;
  
  private int colorType = COLOR_TYPE_RGB;
  private boolean hasAdobeMarker = false;
  
  public BufferedImage readImage(File file) throws IOException, ImageReadException {
      colorType = COLOR_TYPE_RGB;
      hasAdobeMarker = false;
  
      ImageInputStream stream = ImageIO.createImageInputStream(file);
      Iterator&lt;ImageReader&gt; iter = ImageIO.getImageReaders(stream);
      while (iter.hasNext()) {
          ImageReader reader = iter.next();
          reader.setInput(stream);
  
          BufferedImage image;
          ICC_Profile profile = null;
          try {
              image = reader.read(0);
          } catch (IIOException e) {
              System.out.println("Hello");
              colorType = COLOR_TYPE_CMYK;
              checkAdobeMarker(file);
              profile = Sanselan.getICCProfile(file);
  
              WritableRaster raster = (WritableRaster) reader.readRaster(0, null);
              if (colorType == COLOR_TYPE_YCCK)
                  convertYcckToCmyk(raster);
              if (hasAdobeMarker)
                  convertInvertedColors(raster);
              image = convertCmykToRgb(raster, profile);
              System.out.println("Hello");
          }finally {
              try {
                  System.out.println("facebook");
                  stream.close();
              } catch (IOException ioex) {
                  //omitted.
              }
          }
  
          return image;
      }
  
      return null;
  }
  
  public void checkAdobeMarker(File file) throws IOException, ImageReadException {
      JpegImageParser parser = new JpegImageParser();
      ByteSource byteSource = new ByteSourceFile(file);
      @SuppressWarnings("rawtypes")
      ArrayList segments = parser.readSegments(byteSource, new int[] { 0xffee }, true);
      if (segments != null &amp;&amp; segments.size() &gt;= 1) {
          UnknownSegment app14Segment = (UnknownSegment) segments.get(0);
          byte[] data = app14Segment.bytes;
          if (data.length &gt;= 12 &amp;&amp; data[0] == 'A' &amp;&amp; data[1] == 'd' &amp;&amp; data[2] == 'o' &amp;&amp; data[3] == 'b' &amp;&amp; data[4] == 'e')
          {
              hasAdobeMarker = true;
              int transform = app14Segment.bytes[11] &amp; 0xff;
              if (transform == 2)
                  colorType = COLOR_TYPE_YCCK;
          }
      }
  }
  
  public static void convertYcckToCmyk(WritableRaster raster) {
      int height = raster.getHeight();
      int width = raster.getWidth();
      int stride = width * 4;
      int[] pixelRow = new int[stride];
      for (int h = 0; h &lt; height; h++) {
          raster.getPixels(0, h, width, 1, pixelRow);
  
          for (int x = 0; x &lt; stride; x += 4) {
              int y = pixelRow[x];
              int cb = pixelRow[x + 1];
              int cr = pixelRow[x + 2];
  
              int c = (int) (y + 1.402 * cr - 178.956);
              int m = (int) (y - 0.34414 * cb - 0.71414 * cr + 135.95984);
              y = (int) (y + 1.772 * cb - 226.316);
  
              if (c &lt; 0) c = 0; else if (c &gt; 255) c = 255;
              if (m &lt; 0) m = 0; else if (m &gt; 255) m = 255;
              if (y &lt; 0) y = 0; else if (y &gt; 255) y = 255;
  
              pixelRow[x] = 255 - c;
              pixelRow[x + 1] = 255 - m;
              pixelRow[x + 2] = 255 - y;
          }
  
          raster.setPixels(0, h, width, 1, pixelRow);
      }
  }
  
  public static void convertInvertedColors(WritableRaster raster) {
      int height = raster.getHeight();
      int width = raster.getWidth();
      int stride = width * 4;
      int[] pixelRow = new int[stride];
      for (int h = 0; h &lt; height; h++) {
          raster.getPixels(0, h, width, 1, pixelRow);
          for (int x = 0; x &lt; stride; x++)
              pixelRow[x] = 255 - pixelRow[x];
          raster.setPixels(0, h, width, 1, pixelRow);
      }
  }
  
  public static BufferedImage convertCmykToRgb(Raster cmykRaster, ICC_Profile cmykProfile) throws IOException {
      if (cmykProfile == null)
          cmykProfile = ICC_Profile.getInstance(JpegReader.class.getResourceAsStream("/ISOcoated_v2_300_eci.icc"));
  
      if (cmykProfile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) {
          byte[] profileData = cmykProfile.getData();
  
          if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) {
              intToBigEndian(ICC_Profile.icSigDisplayClass, profileData, ICC_Profile.icHdrDeviceClass); // Header is first
  
              cmykProfile = ICC_Profile.getInstance(profileData);
          }
      }
  
      ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);
      BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(), cmykRaster.getHeight(), BufferedImage.TYPE_INT_RGB);
      WritableRaster rgbRaster = rgbImage.getRaster();
      ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();
      ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);
      cmykToRgb.filter(cmykRaster, rgbRaster);
      return rgbImage;
  }
  static void intToBigEndian(int value, byte[] array, int index) {
      array[index]   = (byte) (value &gt;&gt; 24);
      array[index+1] = (byte) (value &gt;&gt; 16);
      array[index+2] = (byte) (value &gt;&gt;  8);
      array[index+3] = (byte) (value);
  }
  }
  </code></pre>
  
  <p>I am using sanselan-0.97-incubator.jar. </p>
  
  <p>If I run this program 31 times approximately, I will get a java heap space error, so I suspect I have a memory leak.</p>
  
  <p>Please help me find the memory leak or suggest how to fix the issue.</p>
  
  <p>Also let me know if the jar file I'm using is OKAY, or maybe it's outdated. I had some issues locating a sanselan jar file.</p>
  
  <p>Thanks in advance.</p>