内存很少时取消设置实例

时间:2017-04-21 04:28:37

标签: java memory-management garbage-collection

我有一个方法可以创建一些重型对象作为缓存。这些对象很少被访问,但是昂贵且处理速度很慢,并且仅按按需进行初始化。然后在使用我的应用程序时,例如,我可以请求大约三个这样的重物,然后重复使用它们,但也有可能我运行一次它只占用内存,而我在会话期间再也不会使用它。

我的问题是:我可以定义一个对象是" 垃圾收集",如果应用程序需要更多内存,它会取消设置这些未使用的数据?

我认为它应该像那样(伪代码):

private static MyInstance instance = null;

public static getInstance() {
    if (instance == null) {
        instance = calculate();
        GC.put(instance);
    }

    return instance;
}

我认为我可以用某种Timer来做,然后不时检查,但我想Java应该有这样的东西,只有在内存占用很多的情况下才能调用。

3 个答案:

答案 0 :(得分:1)

Java无法手动取消分配内存(请参阅Memory Management in Java。但是,它确实有自动垃圾回收。这意味着任何没有引用的对象都会留在程序将被自动删除。例如,在你的情况下,如果不再使用Instance(使用它的函数返回,并且不存在其他引用,或者你覆盖存储引用的唯一变量<{1}}还有其他东西),Instance将被垃圾收集。

,但是,使Instance消失的任何方法都比删除对它的引用更快,并让垃圾收集器处理它。

对于您的应用程序,我建议使用LRU缓存(请参阅How would you implement an LRU cache in Java?),这会将您的内存使用限制为数量实例,(取决于Instance究竟是什么)会将您限制为Instance使用的设定内存量。

如果您希望允许使用任意数量的内存,但不用于很长时间,您可以为Instance创建一个包装类,它实现了您的缓存创意(只有在调用时才会创建Instance,如果其当前副本为Instance),但会保留计时器并在给定时间过期后将其null设置为Instance它被使用了。

答案 1 :(得分:1)

您需要的是适当的缓存实施。 Java中有很多它们,例如Guava Cache,它是高度可配置的。

您的calculate方法只是CacheLoader#load

您不需要关心GC。只需正确调整缓存大小,以免使用太多内存。自动收集被驱逐的缓存条目(未在别处引用时)。

  

我认为我可以用某种Timer来做,然后不时检查,但我想Java应该有这样的东西,只有在内存占用很多的情况下才能调用。

你可以使用基于时间的驱逐CacheBuilder#expireAfterWrite。 Java本身没有缓存,但有SoftReference。无论如何,我不建议直接使用它,但考虑将其与CacheBuilder#softKeys一起使用。

答案 2 :(得分:1)

是的,Java提供了对内存使用敏感的three types of indirect references

缓存可以使用在进程引发OutOfMemoryError之前将被清除的SoftReference。但是,只要有足够的内存,SoftReference就会阻止它的引用被垃圾收集。