我一直想知道Runtime.getRuntime().totalMemory(),Runtime.getRuntime().freeMemory()和Runtime.getRuntime().maxMemory()的确切含义是什么 .
我的理解是,Runtime.getRuntime().totalMemory()返回我的进程使用的总内存.那是对的吗?
如何freeMemory()与maxMemory()?
che*_*eym 225
名称和价值令人困惑.如果您正在寻找总可用内存,则必须自行计算此值.这不是你得到的freeMemory();.
请参阅以下指南:
总指定内存,这将等于配置的-Xmx值:
调用Runtime.getRuntime()maxMemory();
当前分配的空闲内存,是为新对象准备的当前分配空间.注意这不是可用的总内存:
调用Runtime.getRuntime()freeMemory();
已分配的内存总量,是为java进程保留的总分配空间:
调用Runtime.getRuntime()totalMemory();
已用内存,必须计算:
usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
总可用内存,必须计算:
freeMemory = Runtime.getRuntime().maxMemory() - usedMemory;
图片可能有助于澄清:
Ami*_*ani 182
根据API
totalMemory()
Run Code Online (Sandbox Code Playgroud)
返回Java虚拟机中的内存总量.此方法返回的值可能会随着时间的推移而变化,具体取决于主机环境.请注意,保存任何给定类型的对象所需的内存量可能与实现有关.
maxMemory()
Run Code Online (Sandbox Code Playgroud)
返回Java虚拟机将尝试使用的最大内存量.如果没有固有限制,则返回值Long.MAX_VALUE.
freeMemory()
Run Code Online (Sandbox Code Playgroud)
返回Java虚拟机中的可用内存量.调用gc方法可能会导致freeMemory返回的值增加.
在参考您的问题时,maxMemory()返回-Xmx值.
你可能会奇怪为什么有totalMemory()和A maxMemory() .答案是JVM懒惰地分配内存.让我们说你开始你的Java过程:
java -Xms64m -Xmx1024m Foo
Run Code Online (Sandbox Code Playgroud)
你的进程以64mb的内存开始,如果它需要更多(最多1024m),它将分配内存. totalMemory()对应于JVM 当前可用于Foo 的内存量.如果JVM需要更多的内存,它会懒洋洋地分配它达到最大内存.如果你运行-Xms1024m -Xmx1024m,你获得的价值totalMemory()和maxMemory()将等于.
此外,如果要准确计算已用内存量,请执行以下计算:
final long usedMem = totalMemory() - freeMemory();
Run Code Online (Sandbox Code Playgroud)
Sri*_*ram 11
要更好地理解它,请运行以下程序(在jdk1.7.x中):
Run Code Online (Sandbox Code Playgroud)$ 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");
}
}
Run Code Online (Sandbox Code Playgroud)
所有其他答案的编纂版本(撰写本文时):
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());
}
}
Run Code Online (Sandbox Code Playgroud)
Runtime#totalMemory - 到目前为止JVM分配的内存.这不一定是使用中的或最大的.
Runtime#maxMemory - JVM配置使用的最大内存量.一旦您的流程达到此数量,JVM将不会更频繁地分配更多,而是GC.
Runtime#freeMemory - 我不确定这是从最大值还是未使用总量的部分来衡量的.我猜测它是未使用的总量的一部分.
小智 5
垃圾收集机制可以使JVM堆大小可扩展和收缩.但是,它无法分配超过最大内存大小:Runtime.maxMemory.这是最大记忆的意义.总内存意味着分配的堆大小.空闲内存意味着总内存中可用的大小.
例子)java -Xms20M -Xmn10M -Xmx50M ~~~.这意味着jvm应该在start(ms)上分配堆20M.在这种情况下,总内存为20M.空闲内存是20M使用的大小.如果需要更多堆,JVM分配更多但不能超过50M(mx).在最大值的情况下,总内存为50M,自由大小为50M使用的大小.至于最小大小(mn),如果堆使用不多,jvm可以将堆大小缩小到10M.
这种机制是为了提高记忆效率.如果小型java程序在巨大的固定大小堆内存上运行,那么大量内存可能会浪费.
| 归档时间: |
|
| 查看次数: |
88137 次 |
| 最近记录: |