免费内存和垃圾收集器

时间:2016-11-02 13:52:28

标签: java memory javafx garbage-collection

我有一个JavaFX应用程序,它显示带有多个选项卡的TabPane,就像普通的浏览器一样。

我通常在这些标签内加载一些网格。每次选择选项卡时,旧选项卡内容将被删除,并且(从服务器)加载新选项卡。

问题是当您单击旧选项卡时,您必须等待它再次加载。 我希望与现代浏览器具有相同的行为,并将内容保存在我的应用程序中。问题是,我不知道我的应用程序有多少内存,以及可以打开多少选项卡。

基本上,我正在做的是检查我剩下多少内存(通过遵循这个答案Java get available memory),如果我做空,我只是发布所有标签内容。因此,我的应用程序可以运行800Mo的内存,但如果有人有6Go的内存,体验会更好。

在内存释放过程结束时,我手动调用垃圾收集器,因为我已经看到释放我的选项卡内容(允许它们被垃圾收集)并不是立竿见影的。我知道这很糟糕,但另一方面,我依赖垃圾收集器。如果它没有被调用,这不是问题,我的标签的内容将在某个时刻被收集。 这就是所谓的方法:

/**
 * Before an action that may take some memory, we check how much memory we
 * have left. If memory is short, we go through the Tab in order to release
 * them if possible.
 */
public void verifyMemory() {
    long allocatedMemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
    long memoryLeft = Runtime.getRuntime().maxMemory() - allocatedMemory;
    System.out.println(memoryLeft/1000000);
    //We must release some memory
    if (memoryLeft < MEMORY_TRESHOLD) {
        LOGGER.warn("Memory treshold is hit, we must release memory");
        for (Tab tab : getTabs()) {
            if (tab instanceof MyTab) {
                ((MyTab) tab).destroyIfPossible();
            }
        }
        System.gc();
    }
}

您是否有强烈的建议反对我的解决方案?或者任何可以改善或帮助我实现目标的想法?

1 个答案:

答案 0 :(得分:2)

处理这种情况的标准方法是构建一个缓存,使用SoftReference将未使用的对象保留在缓存中,直到GC决定它必须释放该内存。

可以通过-XX:SoftRefLRUPolicyMSPerMB选项调整(稍微笨拙)确切的行为,但基本原则是可用的内存越多,保留的软引用对象就越长。 (与弱引用不同,which are cleared out at the first opportunity。)

(请注意,SoftReference存在一些限制其作为常规缓存解决方案的用途的问题:例如,它们在整个VM中共享,或者至少需要< strong>两个 GC循环清除。但它们非常适合在独立应用程序中缓存一些大型对象。)

例如,Guava的CacheBuilder提供了创建这种缓存的方法。

相关问题