複数の画像からヒストグラムを作成したい。 このプロセスを実行するには、DataBufferByte
にアクセスします。ヒストグラムを作成した後にGCがメモリを解放しないことを認識しました。 このコードで何が問題になっていますか?ご支援のためのBufferedImageのピクセルアクセス - メモリリーク?
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO;
public class Histogram {
HashMap<Color,AtomicInteger> histogram;
public Histogram() {
histogram = new HashMap<>();
}
public void build(BufferedImage image){
int pixelLength = 3;
byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
int red, green, blue;
Color color;
for (int pixel = 0; pixel <= pixels.length - pixelLength; pixel+= pixelLength) {
blue= ((int) pixels[pixel] & 0xff); // blue
green= (((int) pixels[pixel + 1] & 0xff)); // green
red = (((int) pixels[pixel + 2] & 0xff)); // red
color = new Color(red, green, blue);
if(histogram.containsKey(color)){
histogram.get(color).incrementAndGet();
}
else{
histogram.put(color, new AtomicInteger(1));
}
}
pixels = null;
}
public static void main(String[] args) {
String pathImage = "C://testjpg";
try {
for (int j = 0; j < 5000; j++) {
BufferedImage i = ImageIO.read(new File(pathImage));
Histogram h = new Histogram();
h.build(i);
i.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
感謝:)
まず、GCはメモリをただちに回収しません。第2に、 'BufferedImage'の' flush() 'はピクセルデータを解放しません(ビデオRAMのキャッシュされた表現である"表面データ "のみをフラッシュします)。あなたの 'i'変数で参照される' BufferedImage'は、あなたのループの各繰り返しの後にGC *で利用可能ですが、すぐには発生しないかもしれません。 – haraldK
...言い換えれば、ここに何も間違っていません... :-) – haraldK
大丈夫です - ありがとうございます。私は非常に興味があると思う...私はヒストグラムコードをTomcat Webアプリケーションで使用し、ループ内の10,000以上の画像からヒストグラムを抽出します。そこではメモリが非常に急速に増加します(私はこの時点でヒストグラムを保存しませんが、Tomcatは10GB以上のRAMを必要とします)。 Windowsマシンでスタンドアロンのプログラムを実行すると、うまく見えます... –