【问题标题】:how to close an opened Image, java/javafx如何关闭打开的图像,java/javafx
【发布时间】:2016-06-26 13:58:44
【问题描述】:

我正在使用java 制作一个简单的图片查看器,使用javafx
打开大约10张照片后,它需要大量的内存!

显然我需要正确关闭打开的图片(现在没有显示!)(在我的测试/用例中,图片很大!)

这只是代码的一部分...
但这是需要知道的一切

private HashMap<Image, String> adrs;     // a hashMap from thumbNail to address of the image
ObservableList<ImageView> list;          // list of thumbNails
@FXML public ListView<ImageView> pics;
@FXML public ImageView preview;

public void init(String[] picAdrs){

    loadThumbNails(picAdrs);                    // initializes thumbNails (list)
    pics.setItems(list);

    pics.getSelectionModel().selectedItemProperty().addListener((v, oldvalue, newvalue) -> {
        // --> this is where the previous value of "preview.getImage()" should be closed <--
        // (and i don't know how!)
        preview.setImage( new Image(adrs.get(newvalue.getImage()));
        // and more (not related codes...)
    }
}

private void loadThumbNails(String[] picAdrs){
    // initializing list & adrs
    for(String i : picAdrs){

        Image img = new Image(new File(i).toURI().toString(), 200, 0, true, false);
        ImageView iv = new ImageView();
        iv.setImage(img);  

        adrs.put(img, new File(i).toURI().toString());
        list.add(iv);
    }


}

thumbNails 在左侧,“预览”在右侧:
Just a preview of the Scene

因为它看起来很简单! ... 一个简单的方法将不胜感激!
顺便说一句...代码有效,它只是关于我评论的部分

我使用垃圾收集器减少了大约 50% 的内存使用,但 我仍然想要更好的方法,因为我知道 system.gc 不可靠

这里是打开 30 个缩略图和一张完整质量图片的日志:

【问题讨论】:

  • 请贴出负责加载图片的代码,并描述用户如何在不同图片之间切换。
  • @Collins.A 这篇文章是关于删除...已经阅读过...反正 tnx
  • @fabian 代码和添加的屏幕截图...用户可以通过从 thumbNails 中选择缩略图来预览图片(“图片”有一个监听器)
  • 你用过vusualVM或类似的东西吗?如果不是...内存可能可用于垃圾收集,即使它实际上并没有被释放...

标签: java javafx


【解决方案1】:

您需要删除对图像的所有引用。 ImageView 中有对 Image 的引用,因此您需要同时删除对 ImageView 的所有引用,或者将 ImageView 中的 image 字段设置为 null。

我在您的代码中看到三个集合,其中对 Image 或 ImageView 的引用可能会持续存在。

private HashMap<Image, String> adrs;     // a hashMap from thumbNail to address of the image
ObservableList<ImageView> list;          // list of thumbNails
@FXML public ListView<ImageView> pics;

您必须找到一种方法从这些集合中删除这些对象。只要他们在那里,他们就会占用内存。

我会考虑做的不是存储 Image 和 ImageView 对象本身,而是存储它们的 URL。 URL 可以指向文件或 http 位置。然后实时加载。如果您想提前加载所有内容,那么使用 ram 就是成本。

此外,在您的旅行期间,请查看 WeakHashMap。这是一个地图,它将为您删除旧的引用,从而释放您的内存。因此,您只需专注于将图像/图像视图添加到您的集合中,然后让 Java 的 WeakHashMap 将它们删除。

【讨论】:

  • preview ImageView 中的图像被替换时,似乎所有对全尺寸图像的引用都已被删除。此外,adrslist 中的 Images 似乎已经被下采样了。
  • 我加载的唯一内容是缩略图和地址(网址?),每张图片都被选中,一张图片完全加载到预览中,下一张图片被选中,上一张图片(在预览中,没有不再引用)留在内存中
  • @fabian 用新的 ImageView 替换预览而不是交换 Image 字段怎么样?
  • @JoseMartinez:我前段时间对此进行了测试,由于某种原因,当我刚刚从父子列表中删除了 ImageView 时,Image 数据不可用于垃圾收集,但它可用当我用null 替换ImageView 中的图像时(替换Image 很可能也可以)。
【解决方案2】:

到目前为止,似乎没有一个简单的方法...
finilize() 可能有用...(但还不知道如何使用它!)

delete-unused-variables-memory-in-java 的回答下,我设法将内存使用量减少到 100mb 以下。但是由于它使用的是 gc,所以它并不可靠(System.gc 命令可能不会运行 gc)

【讨论】:

    猜你喜欢
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多