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?
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.
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.
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.
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
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With