Java:调用Runtime.freeMemory(),Runtime.totalMemory()和Runtime.maxMemory()的代价

mar*_*ssi 9 java memory performance garbage-collection jvm

我有一个Map内存存储我的对象.当我内存不足时,我想要记忆.我现在正在这样做:

void add(K key, V value) {
    if (underPressure()) {
        flush(innerMap);
    }
    innerMap.add(k, v);
}

boolean underPressure() {
    Runtime rt = Runtime.getRuntime();
    long maxMemory = rt.maxMemory();
    long freeMemory = rt.freeMemory();

    return (double) freeMemory / maxMemory < threshold;
}
Run Code Online (Sandbox Code Playgroud)

正如underPressure()每个插页所称,它有多贵?根据我的理解,因为它是一个近似值,它应该以某种方式被jvm 缓存,但是有没有人真正了解这个?

cru*_*tex 5

从Java 7开始,不再需要轮询空闲内存.可以注册垃圾收集事件.请看这篇文章:http://www.fasterj.com/articles/gcnotifs.shtml

所以我能想到的最好方法是在垃圾收集后检查可用内存,然后在需要时释放额外空间.


pgr*_*ras 2

不直接回答你的问题,但正如评论中已经说过的,freeMemory计算的是可用内存,而不是 GC 后可用的内存,因此,如果你在 GC 运行之前调用freeMemory,你可能会认为你已经达到了“underPressure”限制但在下一次 GC 运行后您也可以拥有足够的可用内存。

另一种方法可能是创建一个软可达对象并检查它是否被 GC 声明:

就像是:

SoftReference<Object> sr = new SoftReference<Object>(new Object(),new ReferenceQueue<Object>());
public boolean underPressure(){
    if (sr.isEnqueued()) {
        // recreate object to monitor
        sr = new SoftReference<Object>(new Object(),new ReferenceQueue<Object>());
        return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)