en エントリとして a を受け取りList<PDXObjectImage> list
、これらの要素ごとに小さなアイコンを作成して JTable に格納する関数を作成する必要があります。
PDXObjectImage
ここで、プログラムがスローしないように、イメージ全体をロードせずにからアイコンを作成する方法を見つけましたOutOfMemoryError: Java heap space
。
for(int k=0;k<list.size();k++)
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
list.get(k).write2OutputStream(output);
ByteArrayInputStream bais = new ByteArrayInputStream(output.toByteArray());
ImageInputStream iis = ImageIO.createImageInputStream(bais);
Iterator iter = ImageIO.getImageReaders(iis);
if (iter.hasNext()) {
ImageReader reader = (ImageReader) iter.next();
reader.setInput(iis, true, true);
ImageReadParam params = reader.getDefaultReadParam();
params.setSourceSubsampling(2.0, 2.0, 0, 0);
BufferedImage img = reader.read(0, params);
ImageIcon imageIcon = new ImageIcon(img);
model.addRow(new Object[]{imageIcon});
}
}
毎回OutOfMemoryError: Java heap space
画像をロードするのではなく、リーダーを使用してリスト内の少量の画像を回避することができました。BufferedImage
残念ながら、84 を超える要素がリストに格納されている場合でも、このエラーが発生します。
jvisualvm を使用して、どのオブジェクトがすべてのヒープ領域を占めているかを確認したところ、それがbyte[]
オブジェクトであることがわかりました (約 85%)。
問題は、すべてのストリームを作成してiconImage
. ImageInputStream
問題は、毎回新しいストリームを作成せずに を取得する方法がわかりません。
単一の関数ですべてのストリームを生成することにより、問題を回避しようとしました:
private ImageInputStream fct(PDXObjectImage img) throws IOException{
ByteArrayOutputStream output = new ByteArrayOutputStream();
img.write2OutputStream(output);
ByteArrayInputStream bais = new ByteArrayInputStream(output.toByteArray());
return ImageIO.createImageInputStream(bais);
}
スコープの終わりに到達すると、Javaが自動的にオブジェクトを削除すると考えています。
各ループの最後に、可能な順序で次を追加してみました:
output.reset();
output.flush();
bais.reset();
bais.close();
iis.flush();
output=null;
bais=null;
iis=null;
System.gc();
また、関数のスコープ外でストリームをインスタンス化しようとしましたが、キーワードを使用せずにaByteArrayInputStream
から aを設定する方法がないため、新しいオブジェクトを作成します。byte[]
new
それでも同じエラーが発生します。何も機能しません。
いくつかの投稿を読みましたが、関連性がStatements
ありResultSets
ませんでした。(多分私は間違っている)
このエラーを回避する方法を誰かが知っていれば、とても感謝しています。
ありがとうございました
編集:
次のようになるようにコードを変更しました。
for(int k=0;k<list.size();k++)
{
list.get(k).write2OutputStream(cbb.getOutputStream());
ImageInputStream iis = ImageIO.createImageInputStream(cbb.getInputStream());
Iterator iter = ImageIO.getImageReaders(iis);
if (iter.hasNext()) {
ImageReader reader = (ImageReader) iter.next();
reader.setInput(iis, true, true);
BufferedImage img = reader.read(0, null);
ImageIcon imageIcon = new ImageIcon(img);
model.addRow(new Object[]{imageIcon});
}
}
また、リーダーにリスナーを追加して、完了した読み取りのパーセンテージを出力できるようにしました。常に 84.2% まで上がり、停止します。
どうすればこれが可能になるか知っている人はいますか?