简体   繁体   English

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

[英]Java: on the cost of calling Runtime.freeMemory(), Runtime.totalMemory() and Runtime.maxMemory()

I have a Map in memory that stores my objects. 我在内存中有一个存储我的对象的Map I'd like to flush to memory when I'm running out of memory. 当我内存不足时,我想要记忆。 I'm doing this right now: 我现在正在这样做:

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;
}

As underPressure() is called at each insert, how expensive is it? 因为在每个插入物处调用underPressure() ,它有多贵? To my understanding, as it's an approximation, it should be somehow cached by the jvm, but does anybody know more about this for real? 根据我的理解,因为它是一个近似值,它应该以某种方式被jvm 缓存 ,但是有没有人真正了解这个?

Since Java 7 there is no need to poll the free memory any more. 从Java 7开始,不再需要轮询空闲内存。 It is possible to register for a garbage collection event. 可以注册垃圾收集事件。 See this post: http://www.fasterj.com/articles/gcnotifs.shtml 请看这篇文章: http//www.fasterj.com/articles/gcnotifs.shtml

So the best way I can think of, is to check the free memory after the garbage collection and then free additional space, if needed. 所以我能想到的最好方法是在垃圾收集后检查可用内存,然后在需要时释放额外空间。

Why not use JMXBeans to do this. 为什么不使用JMXBeans来执行此操作。 It was designed to simplify this kind of operations.. 它旨在简化这种操作..

From the docs... 来自文档......

The API provides access to information such as: 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 

Specifically see the example code in MemoryPoolMXBean 具体请参阅MemoryPoolMXBean中的示例代码

Not directly answering your question but as already said in the comments freeMemory counts the free memory rather than the memory that would be available after a GC, thus if you call freeMemory just before the GC runs you may think you are reaching your "underPressure" limit but you could as well have plenty of free memory after the next GC run. 不是直接回答你的问题,但正如评论中已经说过的那样, freeMemory会计算可用内存而不是GC之后可用的内存,因此如果你在GC运行之前调用freeMemory ,你可能会认为你达到了“underPressure”限制但是你可以在下一次GC运行后获得足够的可用内存。

Another approach may be to create a softly reachable object and to check if it was claimed by the GC: 另一种方法可能是创建一个可轻松访问的对象,并检查GC是否声明了它:

something like: 就像是:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM