Take the 2-minute tour ×

Is there any good way to get the remaining memory available to the JVM at run time? The use case of this would be to have web services which fail gracefully when they are nearing their memory limits by refusing new connections with a nice error message "too many people using this, try again later", rather than dying abruptly with an OutOfMemory error.

Note this has nothing to do with calculating/estimating the cost of each object beforehand. In principle I could estimate how much memory my objects take and refuse new connections based on that estimate, but that seems kind of hacky/fragile.

share|improve this question

7 Answers 7

up vote 18 down vote accepted

This sample by William Brendel may be of some use.

public class Main {
  public static void main(String[] args) {
  /* Total number of processors or cores available to the JVM */
  System.out.println("Available processors (cores): " + 

  /* Total amount of free memory available to the JVM */
  System.out.println("Free memory (bytes): " + 

  /* This will return Long.MAX_VALUE if there is no preset limit */
  long maxMemory = Runtime.getRuntime().maxMemory();
  /* Maximum amount of memory the JVM will attempt to use */
  System.out.println("Maximum memory (bytes): " + 
  (maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));

  /* Total memory currently in use by the JVM */
  System.out.println("Total memory (bytes): " + 

  /* Get a list of all filesystem roots on this system */
  File[] roots = File.listRoots();

  /* For each filesystem root, print some info */
  for (File root : roots) {
    System.out.println("File system root: " + root.getAbsolutePath());
    System.out.println("Total space (bytes): " + root.getTotalSpace());
    System.out.println("Free space (bytes): " + root.getFreeSpace());
    System.out.println("Usable space (bytes): " + root.getUsableSpace());
share|improve this answer
the performance of these functions is low? –  Leonardo Galdioli Jan 24 at 11:58
@LeonardoGaldioli what do you mean? The listed methods do not execute sufficiently fast for what you need? What is the context? –  mcoimbra Feb 9 at 18:08
I just want to know if these methods make the application slower significantly –  Leonardo Galdioli Feb 12 at 13:58
@LeonardoGaldioli I do not know at the time. Why don't you try executing that sample with: long startTime = System.currentTimeMillis(); /* INSERT ORIGINAL MEMORY CODE HERE */ long stopTime = System.currentTimeMillis(); long elapsedTime = stopTime - startTime; –  mcoimbra Feb 25 at 0:26
Care to explain the downvotes? –  mcoimbra Sep 15 at 21:44

Note: All the answers so far, even the accepted one, seem to answer the question by saying that Runtime.getRuntime().freeMemory(); gives you the amount of memory which may be allocated until an out-of-memory error occurs. However: this is wrong.

The approximate amount of memory which may be allocated until an out-of-memory error occurs, i.e., the free memory is likely

long presumableFreeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory;


long allocatedMemory      = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory());

Explanation: If you launch the JVM via an -mx parameter (or -Xmx) you specify the maximum amount available to the JVM. Runtime.getRuntime().maxMemory() will give you this amount. From this amount of system memory the JVM will allocate memory in chunks, say for example blocks of 64 mb. At start, the JVM will only allocate such a chunk from the system and not the full amount. Runtime.getRuntime().totalMemory() gives the total memory allocated from the system, while Runtime.getRuntime().freeMemory() gives you the free memory within the total memory allocated.


long definitelyFreeMemory = Runtime.getRuntime().freeMemory());

is the free memory already reserved by the JVM, but it is likely just a small amount. And you will likely get presumableFreeMemory. Of course, you may get an out-of-memory exception even if you tried to allocate an amount smaller than presumableFreeMemory. This may happen if the JVM does not get the next memory chunk from the system. However, on most systems this will never happen and the system will rather start swapping - a situation you like to avoid. W.r.t. to the original question: if -mx is set to a reasonable value, then presumableFreeMemory is a good indicator for the free memory.

share|improve this answer
All good, but why to use double instead of long for memory amounts? –  Vasili Sep 26 at 17:47
@Vasili I assume I am suffering from double-ism... working too much with doubles. Thank you for pointing it out, I made an edit to the answer. –  Christian Fries Sep 26 at 19:38

In addition to using the Runtime methods, you can get some additional memory info using

MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heap = memBean.getHeapMemoryUsage();
MemoryUsage nonheap = memBean.getNonHeapMemoryUsage();

Each MemoryUsage provides init, used, committed and max values. This might be useful if create a memory monitor thread which polls memory and logs it, providing you with a history of memory usage over time. Sometimes it's helpful to see the memory usage over time leading up to the errors.

If you really want to take this to an extreme, create a heap dump thread. Monitor your memory usage over time and when it exceeds certain thresholds do the following (this works on JBoss 5.0 - your mileage may vary):

// init code
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean diagBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class); 

// loop code
// add some code to figure if we have passed some threshold, then

File heapFile = new File(outputDir, "heap-" + curThreshold + ".hprof");
log.info("Dumping heap file " + heapFile.getAbsolutePath());
diagBean.dumpHeap(heapFile.getAbsolutePath(), true);

Later you can review these heap dump files with the eclipse memory analyzer or similar tools to check for memory leaks etc.

share|improve this answer

In addition to the other answer, I would like to note that doing that is not necessarily a good idea, since you might have a cache in your app that uses SoftReferences.

Such a cache would release memory as soon as the JVM reaches its memory limits. Allocating memory, even if there's not enough free memory, would first cause memory to be released by the soft references, and make it available for the allocation.

share|improve this answer

You can always call Runtime.getRuntime().freeMemory().

The other half of the problem, getting the cost of objects, seems more problematic to me.

I think a better solution would be figuring out how to cluster and scale your web services so they can gracefully accept 150% of rated load without denying new connections. Sounds like a sizing exercise would get you a better solution than a code hack.

share|improve this answer
long freeMemory = Runtime.getRuntime().freeMemory();
share|improve this answer

Runtime.getRuntime().freeMemory() is a way to get free memory for JVM at that moment while runtime. Is it good way (or) not it depends completely on your application.

share|improve this answer

Your Answer


