2013-10-07 37 views
5

ImageIO.read()を利用しています。オリジナルアプリケーションのmainメソッドによって呼び出されたクラスはこれです:JavaでのメモリリークImageIO.read()

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); 
} 

} 

私は、私が実際に答えとしてStackOverflowの上にあるこの他のクラスJpegReader、と一緒に上記を使用していますが、私は忘れてしまいました彼を引用する著者の名前。

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<ImageReader> 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 && segments.size() >= 1) { 
     UnknownSegment app14Segment = (UnknownSegment) segments.get(0); 
     byte[] data = app14Segment.bytes; 
     if (data.length >= 12 && data[0] == 'A' && data[1] == 'd' && data[2] == 'o' && data[3] == 'b' && data[4] == 'e') 
     { 
      hasAdobeMarker = true; 
      int transform = app14Segment.bytes[11] & 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 < height; h++) { 
     raster.getPixels(0, h, width, 1, pixelRow); 

     for (int x = 0; x < 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 < 0) c = 0; else if (c > 255) c = 255; 
      if (m < 0) m = 0; else if (m > 255) m = 255; 
      if (y < 0) y = 0; else if (y > 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 < height; h++) { 
     raster.getPixels(0, h, width, 1, pixelRow); 
     for (int x = 0; x < 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 >> 24); 
    array[index+1] = (byte) (value >> 16); 
    array[index+2] = (byte) (value >> 8); 
    array[index+3] = (byte) (value); 
} 
} 

私はsanselan-0.97-incubator.jarを使用しています。

このプログラムを約31回実行すると、Javaヒープスペースエラーが発生するため、メモリリークが発生している可能性があります。

メモリリークを見つけたり、問題を解決する方法を提案してください。

また、私が使用しているjarファイルがOKAYか、それとも古くなっているのかを教えてください。私はsanselan jarファイルを見つける問題をいくつか持っていました。

ありがとうございます。

+0

ヒープサイズの増加はどうですか?たくさんの画像を読み込むとたくさんのメモリが必要になる – Sage

+0

一度にすべての画像を読み込むわけではありません。私はそれらを順番に読み込みます。新しい画像を読み込むと、以前の画像は必要ありません。それで、どういうわけか私は、まだ起こってはいけない、以前の画像をメモリに保持していると結論づけています。それは仮説です。 – ThePrince

+0

このエラーを引き起こすのに十分な単一のイメージはありません。私はそれが以前の画像を保持していると推測しています。 – ThePrince

答えて

3

私はこのコード(JPEGReader)で同じメモリ問題を抱えています。いくつかの試行の後、私はreader.dispose()を呼び出すことでこの問題を解決できることを発見しました。

私が修正した方法を教えてください。それがあなたに役立つことを願っています。

public BufferedImage readImage(File file) throws IOException, ImageReadException { 
    colorType = COLOR_TYPE_RGB; 
    hasAdobeMarker = false; 

    ImageInputStream stream = ImageIO.createImageInputStream(file); 
    try{ 
     Iterator<ImageReader> 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) { 
       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); 
       return image; 
      } 
      finally { 
       reader.dispose(); 
      } 
     } 
     return null; 
    } 
    finally { 
     if (stream != null){ 
      stream.close(); 
     } 
    } 
} 
関連する問題