在Java中将许多缓冲的图像100+加载到内存中

时间:2012-07-25 16:09:09

标签: java out-of-memory bufferedimage

我正在编写一个涉及自定义搜索许多图像的程序。当用户输入他们的搜索标准时,从高速缓存或服务器检索相应的图像。我有一个JTable,显示相应图像的链接。当用户点击链接时,图像显示在JPanel上。单击链接时,我可以从硬盘驱动器中读取图像,但速度不如我想的那么快。加载它需要几秒钟。我尝试过创建一个BufferedImages数组,但是如果搜索返回了很多结果,那么我就去了。我想知道在单击链接时使图像显示更快的最佳方法是什么。

这是我如何获得图像...

Public void getFile(String fileName){
File file = new File("./cache/"+fileName);
    boolean exists = file.exists();

    BufferedImage returnImage =null;
    if(exists){
        try {

            returnImage = ImageIO.read(file);
            System.out.println("Found In Cache!");
        } catch (IOException|IndexOutOfBoundsException e) {
            try {
                if(fileName != null){
                returnImage = downloadImage(fileName);
                System.out.println("Found ON Server :(");
                }
            } catch (IOException |IndexOutOfBoundsException ex) {
                // TODO Auto-generated catch block
                ex.printStackTrace();
            }
        }
    }else{
        try {
            if(fileName != null){
            returnImage = downloadImage(fileName);
            System.out.println("Found ON Server :(");
            }
        } catch (IOException |IndexOutOfBoundsException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return returnImage; 

}
}

这就是我把它们放在一个数组中的地方......

BufferedImage[] images = new BufferedImage[numOfSearchResults];

for(SearchResult r: results){
     images[i] = imageCache.getFile(r.imageName);
}

基本上我只是想知道什么是最好的方法来预先加载图像而不用oom。在此先感谢

4 个答案:

答案 0 :(得分:3)

从磁盘加载图像需要几秒钟,这听起来不合理,除非图像真的非常,真的很大(10百万像素或更多)。首先确定实际花费的时间。

对于缓存,您可以使用java.lang.ref.SoftReference保存对您加载的每个图像的引用 - 这允许在运行OOM之前对图像进行垃圾收集。 如果真的不可避免,我将使用多层缓存系统,第一级使用内存中的SoftReferences,而基于服务器的映像则使用额外的磁盘缓存。在查找图像时,首先检查内存中的缓存,如果没有找到任何内容,则检查磁盘缓存,如果仍未找到,则以常规方式加载图像。

答案 1 :(得分:2)

不要加载所有/太多图像,在当前索引之前加载几个图像,并在当前索引之后耦合图像。

将图像加载器实现为一个不同的线程,当用户正在观看当前加载的图像时,该线程不会阻止主执行线程并加载其他图像。

答案 2 :(得分:0)

您可以打开所有图像的InputStream并关闭用户未点击的图像,只需使用您需要的图像。

通过这种方式,您无需缓冲所有图片,但在用户点击时已经“触手可及”。

但是正如@Robin正确评论的那样,加载平均大小的图片真的不需要很长时间。

我不确定这对你的表现有多大帮助,但根据你的情况,它可以。

答案 3 :(得分:0)

如果您不需要全尺寸图像,我会在加载时缩小它们以减少内存量。你必须记住,内存中的图像加载不再被压缩。

如果您可以控制源图像,我会考虑生成缩略图以帮助它们加载更快。我们使用200x200&的缩略图。即使在基于SMB的共享中,它们也需要不到一秒的时间来加载