OOME:Java堆空间-还有其他选项吗?
我正在创建一个Java应用程序,它可以读取输入图像,然后创建一个结合颜色的输出图像,我制作了一个这样的应用程序,它可以读取TIFF文件。输入图像需要是多光谱卫星图像,其中通常相当大。通过读取TIFF文件,在本地将其保存为PNG,然后将保存的PNG读取为BuffereImage,Im将转换为PNG。保存的PNG大约是35MB大小的一半。 如果可能的话,我真的不想扩展堆的大小,如果我能找到一种方法来重新分配内存,那会很好,如果我能找到一种方法来做的话。但我猜使用大型图像文件意味着这是不可避免的,特别是当我需要使用BuffereImage并且可能需要使用更多的时候 下面可以看到im使用的代码,重复了3次,因此读取、保存了3个TIFF文件,然后在生成PNG时读取。基本上,在读取TIFF文件后,我从不需要它们,但在任何时候都不需要,这样会占用大量内存,有没有办法回收这些内存OOME:Java堆空间-还有其他选项吗?,java,image-processing,garbage-collection,Java,Image Processing,Garbage Collection,我正在创建一个Java应用程序,它可以读取输入图像,然后创建一个结合颜色的输出图像,我制作了一个这样的应用程序,它可以读取TIFF文件。输入图像需要是多光谱卫星图像,其中通常相当大。通过读取TIFF文件,在本地将其保存为PNG,然后将保存的PNG读取为BuffereImage,Im将转换为PNG。保存的PNG大约是35MB大小的一半。 如果可能的话,我真的不想扩展堆的大小,如果我能找到一种方法来重新分配内存,那会很好,如果我能找到一种方法来做的话。但我猜使用大型图像文件意味着这是不可避免的,特别
当你说你已经使它能够读取TIFF文件时,这是否意味着你实现了一个定制的ImageReader?如果是这样,读卡器是否可能没有清理某些资源?没有im使用BuffereImage处理TIFF文件,使用JAI,这可以在以下行中完成:BuffereImage bi3=ImageIO.readfile3;ImageIO.writebi3,PNG,新文件img3_tmp.PNG;您是否真的看到了OutOfMemoryErrors,或者只是担心它们的潜在性?只要原始BuffereImage没有在其他任何地方被引用,就应该将其标记为GC,并在VM需要内存时收集。如果您看到OOMEs,那么可能是您正在积极使用的数据,即您的3个较小的文件以及用于组合它们的任何对象,我认为您在这里显示的这些文件对于堆设置来说都太大了。您是否进行过内存分析以查看堆的实际使用情况?我在尝试加载最终映像时看到了错误,我刚刚运行了内存分析程序,使用的最大堆大小是195mb或235mb,这对我来说似乎没有多大意义。它确实会尖峰,我假设当它重新加载PNG时,会使其超过235mb。由于堆被分为多个代,可能一代中的空间就用完了,这可能解释了为什么尽管没有达到最大堆大小,但仍然会出现OOMEs。我个人从未对代大小进行过任何微调,但这可能值得研究:
private void importBlueActionPerformed(java.awt.event.ActionEvent evt) {
int img3 = blueFileChooser.showOpenDialog(this);
if(img3==JFileChooser.APPROVE_OPTION)
{
try {
File file3 = blueFileChooser.getSelectedFile();
BufferedImage bi3 = ImageIO.read(file3);
ImageIO.write(bi3, "PNG", new File("img3_tmp.png"));
image3 = ImageIO.read(new File("img3_tmp.png"));
//image3 = new BufferedImage(img3_tmp.getWidth(), img3_tmp.getHeight(), BufferedImage.TYPE_INT_ARGB);
ImageIcon imageIcon3 = new ImageIcon(image3);
Image blueInput = imageIcon3.getImage().getScaledInstance(300, 300, Image.SCALE_SMOOTH);
imageIcon3.setImage(blueInput);
blueLabel.setIcon(imageIcon3);
System.out.println(file3+"\n"+image3);
inputCounter++;
checkInput();
} catch (IOException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}