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

时间:2011-12-15 16:40:37

标签: java performance memory 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;
}

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

3 个答案:

答案 0 :(得分:5)

从Java 7开始,不再需要轮询空闲内存。可以注册垃圾收集事件。请参阅此帖子:http://www.fasterj.com/articles/gcnotifs.shtml

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

答案 1 :(得分:3)

为什么不使用JMXBeans来执行此操作。它旨在简化这种操作。

来自文档...

  

API提供对以下信息的访问:

Number of classes loaded and threads running
Virtual machine uptime, system properties, and JVM input arguments
Thread state, thread contention statistics, and stack trace of live threads
Memory consumption
Garbage collection statistics
Low memory detection
On-demand deadlock detection
Operating system information

具体请参阅MemoryPoolMXBean

中的示例代码

答案 2 :(得分:2)

没有直接回答你的问题,但正如评论中已经说过的那样 freeMemory 计算可用内存而不是GC之后可用的内存,因此如果你调用 freeMemory 在GC运行之前,你可能会认为你达到了“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;
}