什么是 Runtime.getRuntime () . total Memory ()和 freeMemory () ?

我一直想知道 GetRuntime () . total Memory ()GetRuntime () . freeMemory ()GetRuntime () . maxMemory ()的确切含义是什么。

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

freeMemory()maxMemory()呢?

121136 次浏览

根据 空气污染指数

totalMemory()

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

maxMemory()

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

freeMemory()

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

关于您的问题,maxMemory()返回 -Xmx值。

你可能想知道为什么有一个 Total Memory ()和一个 MaxMemory ()。答案是 JVM 懒惰地分配内存。假设您以这样的方式启动 Java 进程:

java -Xms64m -Xmx1024m Foo

您的进程以64mb 的内存开始,如果需要更多内存(最多1024m) ,它将分配内存。totalMemory()对应于 Foo 的 JVM 可用的内存量 目前。如果 JVM 需要更多的内存,它将延迟地将它分配给最大内存的 起来。如果使用 -Xms1024m -Xmx1024m运行,则从 totalMemory()maxMemory()得到的值将相等。

此外,如果您想要准确地计算 用过内存的数量,您需要进行以下计算:

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

Runtime # talMemory -JVM 到目前为止分配的内存。这不一定是正在使用的或最大值。

Runtime # maxMemory -JVM 配置为使用的最大内存量。一旦您的进程达到这个数量,JVM 将不会分配更多的数据,而是更频繁地分配 GC。

Runtime # freeMemory -我不确定这是从最大值还是总数中未使用的部分来衡量的。我猜这是对未使用部分的一种度量。

通过垃圾收集机制,JVM 堆大小可以增长和收缩。 但是,它不能分配超过最大内存大小的内存: Runtime.maxMemory。这就是最大内存的含义。总内存意味着分配的堆大小。空闲内存意味着总内存中的可用大小。

示例) java-Xms20M-Xmn10M-Xmx50M ~ ~ ~ 。 这意味着 jvm 应该在启动时分配堆20M (ms)。在本例中,总内存为20M。可用内存大小为20M。如果需要更多堆,则 JVM 分配更多堆,但不能超过50M (mx)。在最大值的情况下,总内存为50M,可用大小为50M 使用的大小。至于最小大小(mn) ,如果堆使用不多,jvm 可以将堆大小缩小到10M。

这种机制是为了提高内存的效率。如果小的 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");
}
}

名称和值很混乱。如果你正在寻找的 完全空闲内存你将不得不自己计算这个值。你从 freeMemory();得到什么。

请参阅以下指南:

总指定内存 ,这将等于配置的 Xmx值:

GetRuntime () . maxMemory () ;

当前分配的空闲内存 ,是当前为新对象分配的空间 准备好了。这不是完全可用的 有空内存:

GetRuntime () . freeMemory () ;

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

GetRuntime () . total Memory () ;

使用过的内存 ,必须计算:

UsedMemory = Runtime.getRuntime () . talMemory ()-Runtime.getRuntime () . freeMemory () ;

总自由内存 ,必须计算:

FreeMemory = Runtime.getRuntime () . maxMemory ()-usedMemory;

图片可能有助于澄清:

java runtime memory

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

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="http://www.oracle.com/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());
}
}

可以在 MB 格式中看到结果,除以等于 1MB1024 x 1024

int dataSize = 1024 * 1024;


System.out.println("Used Memory   : " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/dataSize + " MB");
System.out.println("Free Memory   : " + Runtime.getRuntime().freeMemory()/dataSize + " MB");
System.out.println("Total Memory  : " + Runtime.getRuntime().totalMemory()/dataSize + " MB");
System.out.println("Max Memory    : " + Runtime.getRuntime().maxMemory()/dataSize + " MB");