我必须创建一个函数来接收条目 aList<PDXObjectImage> list
并为每个元素创建一个小图标并将它们存储在 JTable 中。
现在我找到了一种从 a 创建图标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();
我还尝试在函数范围之外实例化流,但是如果不使用关键字就无法ByteArrayInputStream
从 a设置 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% 并停止。
有谁知道这怎么可能?