Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a Map in memory that stores my objects. 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? 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?

like image 231
marcorossi Avatar asked Dec 15 '11 16:12

marcorossi


People also ask

What is runtime getRuntime () totalMemory ()?

Runtime. totalMemory() method returns the total amount of memory in the Java virtual machine. The value returned by this method may vary over time, depending on the host environment. Note that the amount of memory required to hold an object of any given type may be implementation-dependent.

What is Runtime instance?

In Java, the Runtime class is used to interact with Every Java application that has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime() method.


3 Answers

Since Java 7 there is no need to poll the free memory any more. It is possible to register for a garbage collection event. See this post: 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.

like image 122
cruftex Avatar answered Oct 19 '22 19:10

cruftex


Why not use JMXBeans to do this. It was designed to simplify this kind of operations..

From the docs...

The API provides access to information such as:

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

like image 37
Jayan Avatar answered Oct 19 '22 21:10

Jayan


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.

Another approach may be to create a softly reachable object and to check if it was claimed by the 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;
}
like image 27
pgras Avatar answered Oct 19 '22 19:10

pgras