Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java get available memory

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.

like image 513
Li Haoyi Avatar asked Oct 09 '12 20:10

Li Haoyi


People also ask

How do I get memory in Java?

How to get total Memory in Java. You can use Runtime. getRuntime. totalMemory() to get total memory from JVM which represents the current heap size of JVM which is a combination of used memory currently occupied by objects and free memory available for new objects.

How do I see how much memory is used in Java?

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 are the memories available in Java?

There are two kinds of memory used in Java. These are called stack memory and heap memory.

Can you access memory and storage in Java?

@Peter Lawrey: Yes, you can access memory relative to an object (to read instance fields) or access memory at an absolute location.


1 Answers

This sample by William Brendel may be of some use.

EDIT: I originally provided this sample (linking to William Brendel's answer on another topic). The creator of that topic (Steve M) wanted to create a multi-platform Java application. Specifically, the user was trying to find a means by which to assess the running machine's resources (disk space, CPU and memory usage).

This is an inline transcript of the answer given in that topic. However, it has been pointed out on this topic that it is not the ideal solution, despite my answer being marked as accepted.

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): " +    Runtime.getRuntime().availableProcessors());    /* Total amount of free memory available to the JVM */   System.out.println("Free memory (bytes): " +    Runtime.getRuntime().freeMemory());    /* 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): " +    Runtime.getRuntime().totalMemory());    /* 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());   }  } } 

User Christian Fries points out that it is wrong to assume that Runtime.getRuntime().freeMemory() gives you the amount of memory which may be allocated until an out-of-memory error occurs.

From the documentation, the signature return of Runtime.getRuntime().freeMemory() is as such:

Returns: an approximation to the total amount of memory currently available for future allocated objects, measured in bytes.

However, user Christian Fries claims this function may be misinterpreted. He claims that the approximate amount of memory which may be allocated until an out-of-memory error occurs (the free memory) is likely to be given by:

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

With allocatedMemory being given by:

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

The key here is a discrepancy between the concept of free memory. One thing is the memory that the operating system provides the Java Virtual Machine. Another is the total amount of bytes comprising the chunks of blocks of memory actually being used by the Java Virtual Machine itself.

Considering that memory given to Java applications is managed in blocks by the Java Virtual Machine, the amount of free memory available to the Java Virtual Machine may not exactly match the memory available for a Java application.

Specifically, Christian Fries denotes the usage of the -mx or -Xmx flags to set the maximum amount of memory available to the Java Virtual Machine. He notes the following function differences:

/* Returns the maximum amount of memory available to     the Java Virtual Machine set by the '-mx' or '-Xmx' flags. */ Runtime.getRuntime().maxMemory();  /* Returns the total memory allocated from the system     (which can at most reach the maximum memory value     returned by the previous function). */ Runtime.getRuntime().totalMemory();  /* Returns the free memory *within* the total memory     returned by the previous function. */ Runtime.getRuntime().freeMemory(); 

Christian concludes his answer by stating that Runtime.getRuntime().freeMemory() in fact returns what may be called presumable free memory; even if a future memory allocation does not exceed the value returned by that function, if the Java Virtual Machine has not yet received the actual chunk of memory assigned by the host system, a java.lang.OutOfMemoryError may still be produced.

In the end, the proper method to use will have a varying degree of dependence on the specifics of your application.

I provide another link which may be useful. It is a question made by user Richard Dormand and answered by stones333 about determining the default Java heap size used.

like image 157
Blitzkoder Avatar answered Sep 20 '22 19:09

Blitzkoder