什么是Runtime.getRuntime()。totalMemory()和freeMemory()?

我一直在想, Runtime.getRuntime() , totalMemory() , Runtime.getRuntime(),freeMemory()和Runtime.getRuntime()。maxMemory()是什么意思。

我的理解是, Runtime.getRuntime().totalMemory()返回我的进程正在使用的总内存。 那是对的吗?

如何freeMemory()maxMemory()

根据API

 totalMemory() 

返回Java虚拟机中的总内存量。 此方法返回的值可能随时间而变化,具体取决于主机环境。 请注意,保存任何给定types的对象所需的内存量可能取决于实现。

 maxMemory() 

返回Java虚拟机将尝试使用的最大内存量。 如果没有固有限制,则返回值Long.MAX_VALUE。

 freeMemory() 

返回Java虚拟机中的可用内存量。 调用gc方法可能会增加freeMemory返回的值。

参考你的问题, maxMemory()返回-Xmx值。

你可能想知道为什么有一个totalMemory()和一个maxMemory() 。 答案就是JVM懒洋洋地分配内存。 比方说,你开始你的Java过程如下:

 java -Xms64m -Xmx1024m Foo 

你的进程开始于64MB的内存,如果需要更多(高达1024米),它将分配内存。 totalMemory()对应于当前可用于Foo的JVM的内存量。 如果JVM需要更多的内存,它将懒惰地分配给最大的内存。 如果使用-Xms1024m -Xmx1024m运行, -Xms1024m -Xmx1024m totalMemory()maxMemory()获得的值将相等。

另外,如果要准确计算已使用内存的数量,可以使用以下计算:

 final long usedMem = totalMemory() - freeMemory(); 

名字和价值是混乱。 如果你正在寻找总的空闲内存,你将不得不自己计算这个值。 这不是你从freeMemory();得到的freeMemory();

请参阅以下指南:

总指定内存 ,这将等于configuration的-Xmx值:

调用Runtime.getRuntime()maxMemory();

当前分配的空闲内存 ,是当前为新对象分配的空间。 注意这不是总的可用内存:

调用Runtime.getRuntime()freeMemory();

总分配的内存 ,是为java进程保留的总分配空间:

调用Runtime.getRuntime()totalMemory();

使用的内存 ,必须计算:

usedMemory = Runtime.getRuntime()。totalMemory() – Runtime.getRuntime()。freeMemory();

总空闲内存必须被计算:

freeMemory = Runtime.getRuntime()。maxMemory() – usedMemory;

图片可能有助于澄清:

java运行时内存

为了更好地理解它,运行以下程序(在jdk1.7.x中):

 $ java -Xms1025k -Xmx1025k -XshowSettings:vm MemoryTest 

这将打印jvm选项以及在jvm中可用的免费总计最大内存。

 public class MemoryTest { public static void main(String args[]) { System.out.println("Used Memory : " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) + " bytes"); System.out.println("Free Memory : " + Runtime.getRuntime().freeMemory() + " bytes"); System.out.println("Total Memory : " + Runtime.getRuntime().totalMemory() + " bytes"); System.out.println("Max Memory : " + Runtime.getRuntime().maxMemory() + " bytes"); } } 

运行时#totalMemory – JVM已经分配的内存。 这不一定是在使用或最大的。

运行时#maxMemory – JVMconfiguration使用的最大内存量。 一旦你的过程达到了这个数量,JVM将不会分配更多,而是更频繁地GC。

运行时#freeMemory – 我不确定这是从最大值还是未使用的总部分计算出来的。 我猜测这是一个未使用的总量的一部分。

垃圾收集机制可以使JVM堆大小增长和收缩。 但是,它不能分配超过最大内存大小:Runtime.maxMemory。 这是最大记忆的意思。 内存总量意味着分配的堆大小。 可用内存意味着总内存中可用的大小。

例如)java -Xms20M -Xmn10M -Xmx50M ~~~。 这意味着jvm应该在开始(ms)分配堆20M。 在这种情况下,总内存是20M。 可用内存是20M使用的大小。 如果需要更多的堆,JVM分配更多,但不能超过50M(mx)。 在最大的情况下,总内存为50M,自由大小为50M使用的大小。 至于最小尺寸(mn),如果堆不够用,jvm可以将堆大小缩小到10M。

这个机制是为了内存的效率。 如果小的java程序运行在巨大的固定大小的堆内存上,那么太多的内存可能是浪费的。

所有其他答案的编码版本(撰写本文时):

 import java.io.*; /** * This class is based on <a href="http://stackoverflow.com/users/2478930/cheneym">cheneym</a>'s * <a href="http://stackoverflow.com/a/18375641/253468">awesome interpretation</a> * of the Java {@link Runtime}'s memory query methods, which reflects intuitive thinking. * Also includes comments and observations from others on the same question, and my own experience. * <p> * <img src="https://i.stack.imgur.com/GjuwM.png" alt="Runtime's memory interpretation"> * <p> * <b>JVM memory management crash course</b>: * Java virtual machine process' heap size is bounded by the maximum memory allowed. * The startup and maximum size can be configured by JVM arguments. * JVMs don't allocate the maximum memory on startup as the program running may never require that. * This is to be a good player and not waste system resources unnecessarily. * Instead they allocate some memory and then grow when new allocations require it. * The garbage collector will be run at times to clean up unused objects to prevent this growing. * Many parameters of this management such as when to grow/shrink or which GC to use * can be tuned via advanced configuration parameters on JVM startup. * * @see <a href="http://stackoverflow.com/a/42567450/253468"> * What are Runtime.getRuntime().totalMemory() and freeMemory()?</a> * @see <a href="technetwork/java/javase/memorymanagement-whitepaper-150215.pdf"> * Memory Management in the Sun Java HotSpot™ Virtual Machine</a> * @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html"> * Full VM options reference for Windows</a> * @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html"> * Full VM options reference for Linux, Mac OS X and Solaris</a> * @see <a href="http://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html"> * Java HotSpot VM Options quick reference</a> */ public class SystemMemory { // can be white-box mocked for testing private final Runtime runtime = Runtime.getRuntime(); /** * <b>Total allocated memory</b>: space currently reserved for the JVM heap within the process. * <p> * <i>Caution</i>: this is not the total memory, the JVM may grow the heap for new allocations. */ public long getAllocatedTotal() { return runtime.totalMemory(); } /** * <b>Current allocated free memory</b>: space immediately ready for new objects. * <p> * <i>Caution</i>: this is not the total free available memory, * the JVM may grow the heap for new allocations. */ public long getAllocatedFree() { return runtime.freeMemory(); } /** * <b>Used memory</b>: * Java heap currently used by instantiated objects. * <p> * <i>Caution</i>: May include no longer referenced objects, soft references, etc. * that will be swept away by the next garbage collection. */ public long getUsed() { return getAllocatedTotal() - getAllocatedFree(); } /** * <b>Maximum allocation</b>: the process' allocated memory will not grow any further. * <p> * <i>Caution</i>: This may change over time, do not cache it! * There are some JVMs / garbage collectors that can shrink the allocated process memory. * <p> * <i>Caution</i>: If this is true, the JVM will likely run GC more often. */ public boolean isAtMaximumAllocation() { return getAllocatedTotal() == getTotal(); // = return getUnallocated() == 0; } /** * <b>Unallocated memory</b>: amount of space the process' heap can grow. */ public long getUnallocated() { return getTotal() - getAllocatedTotal(); } /** * <b>Total designated memory</b>: this will equal the configured {@code -Xmx} value. * <p> * <i>Caution</i>: You can never allocate more memory than this, unless you use native code. */ public long getTotal() { return runtime.maxMemory(); } /** * <b>Total free memory</b>: memory available for new Objects, * even at the cost of growing the allocated memory of the process. */ public long getFree() { return getTotal() - getUsed(); // = return getAllocatedFree() + getUnallocated(); } /** * <b>Unbounded memory</b>: there is no inherent limit on free memory. */ public boolean isBounded() { return getTotal() != Long.MAX_VALUE; } /** * Dump of the current state for debugging or understanding the memory divisions. * <p> * <i>Caution</i>: Numbers may not match up exactly as state may change during the call. */ public String getCurrentStats() { StringWriter backing = new StringWriter(); PrintWriter out = new PrintWriter(backing, false); out.printf("Total: allocated %,d (%.1f%%) out of possible %,d; %s, %s %,d%n", getAllocatedTotal(), (float)getAllocatedTotal() / (float)getTotal() * 100, getTotal(), isBounded()? "bounded" : "unbounded", isAtMaximumAllocation()? "maxed out" : "can grow", getUnallocated() ); out.printf("Used: %,d; %.1f%% of total (%,d); %.1f%% of allocated (%,d)%n", getUsed(), (float)getUsed() / (float)getTotal() * 100, getTotal(), (float)getUsed() / (float)getAllocatedTotal() * 100, getAllocatedTotal() ); out.printf("Free: %,d (%.1f%%) out of %,d total; %,d (%.1f%%) out of %,d allocated%n", getFree(), (float)getFree() / (float)getTotal() * 100, getTotal(), getAllocatedFree(), (float)getAllocatedFree() / (float)getAllocatedTotal() * 100, getAllocatedTotal() ); out.flush(); return backing.toString(); } public static void main(String... args) { SystemMemory memory = new SystemMemory(); System.out.println(memory.getCurrentStats()); } }