6

我在将图像加载到我的应用程序时遇到问题。我正在尝试制作一个简单的图像浏览器。在左边我有一个文件夹列表。单击列表图像上的文件夹名称后,应出现在右侧(流窗格)。每个图像都在一个带边框的 HBox 中。但是我很快就遇到了这样的错误:

java.lang.outofmemoryerror java heap space

我查看了任务管理器——如果我只加载 6 张照片,应用程序会占用 500mb 的内存!还有一件事 - 如果我更改列表中的文件夹,内存仍然被占用。在选择另一个文件夹时,我正在创建新的 flowPane

flowPane = new FlowPane();

所以垃圾收集器应该删除所有 ImageViews 的旧的,对吗?

如何有效地管理我的应用程序中的图像?

  for(int i = 0 ; i < zdjecia.length; i++){
        ImageView iv2 = new ImageView();
        Image image = new Image("file:"+zdjecia[i].getAbsolutePath());
         iv2.setImage(image);
         if( image.getHeight() > image.getWidth()){
                iv2.fitHeightProperty().bind(szerokoscZdjecia.multiply(0.8).subtract(6));
        }else
                iv2.fitWidthProperty().bind(szerokoscZdjecia.subtract(6));

         iv2.setPreserveRatio(true);
         iv2.setSmooth(true);
         iv2.setCache(false);

         String styl = "-fx-border-color: #b2b3b3;"
                 + "-fx-border-width: 2;";

         HBox boxNaFotke = new HBox();
         boxNaFotke.prefWidthProperty().bind(szerokoscZdjecia);
         boxNaFotke.prefHeightProperty().bind(szerokoscZdjecia.multiply(0.8));
         boxNaFotke.setAlignment(Pos.CENTER);
         boxNaFotke.setStyle(styl);
         boxNaFotke.getChildren().add(iv2);
         fotki.add(boxNaFotke);
         flowPane.getChildren().add(boxNaFotke);
    }
4

2 回答 2

4

如果Image使用构造函数来扩展,所需的内存量将大大减少。

文档中的一些示例:

// 加载图像并将其大小调整为 100x150,而不保留其原始纵横比
// 该图像位于类路径的 my.res 包中
Image image2 = new Image("my/res/flower.png", 100, 150, false, false);

// 加载图像并将其调整为 100 的宽度,同时保留其
原始纵横比,使用更快的过滤方法
// 通过 http 协议从提供的 URL 下载图像
Image image3 = new Image("http://sample.com/res/flower.png", 100, 0, false, false);

于 2016-04-04T19:42:03.003 回答
0

我在 JavaFX 中的内存有类似的问题,但与 setStyle 方法有关。我分析了堆使用情况,发现 StyleHelper 对象保留了对 setStyle 方法设置的所有样式的所有引用(com.sun.javafx.css.StyleManager$Holder 中有很多具有 GC 根的 HashMap 实例)。当风格经常改变时,这可能是一个问题。

尝试评论 boxNaFotke.setStyle(styl); 行并检查它是否有帮助。

于 2013-03-22T10:34:11.403 回答