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.
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.