简体   繁体   English

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

[英]What are Runtime.getRuntime().totalMemory() and freeMemory()?

I've been wondering what the exact meaning of Runtime.getRuntime().totalMemory() , Runtime.getRuntime().freeMemory() , and Runtime.getRuntime().maxMemory() is. 我一直想知道Runtime.getRuntime()。totalMemory()Runtime.getRuntime()。freeMemory()Runtime.getRuntime()。maxMemory()的确切含义是什么。

My understanding is, Runtime.getRuntime().totalMemory() returns the total memory my process is using. 我的理解是, Runtime.getRuntime().totalMemory()返回我的进程正在使用的总内存。 Is that correct? 那是对的吗?

How about freeMemory() and maxMemory() ? freeMemory()maxMemory()怎么样?

The names and values are confusing. 名称和价值令人困惑。 If you are looking for the total free memory you will have to calculate this value by your self. 如果您正在寻找总可用内存 ,则必须自行计算此值。 It is not what you get from freeMemory(); 这不是你从freeMemory();得到的freeMemory(); .

See the following guide: 请参阅以下指南:

Total designated memory , this will equal the configured -Xmx value: 总指定内存 ,这将等于配置的-Xmx值:

Runtime.getRuntime().maxMemory(); 调用Runtime.getRuntime()maxMemory();

Current allocated free memory , is the current allocated space ready for new objects. 当前分配的空闲内存 ,是为新对象准备的当前分配空间。 Caution this is not the total free available memory: 注意这不是可用的总内存:

Runtime.getRuntime().freeMemory(); 调用Runtime.getRuntime()freeMemory();

Total allocated memory , is the total allocated space reserved for the java process: 已分配的内存总量,是为java进程保留的总分配空间:

Runtime.getRuntime().totalMemory(); 调用Runtime.getRuntime()totalMemory();

Used memory , has to be calculated: 已用内存 ,必须计算:

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

Total free memory , has to be calculated: 总可用内存 ,必须计算:

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

A picture may help to clarify: 图片可能有助于澄清:

java运行时内存

According to the API 根据API

totalMemory()

Returns the total amount of memory in the Java virtual machine. 返回Java虚拟机中的内存总量。 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. 请注意,保存任何给定类型的对象所需的内存量可能与实现有关。

maxMemory()

Returns the maximum amount of memory that the Java virtual machine will attempt to use. 返回Java虚拟机将尝试使用的最大内存量。 If there is no inherent limit then the value Long.MAX_VALUE will be returned. 如果没有固有限制,则返回值Long.MAX_VALUE。

freeMemory()

Returns the amount of free memory in the Java Virtual Machine. 返回Java虚拟机中的可用内存量。 Calling the gc method may result in increasing the value returned by freeMemory. 调用gc方法可能会导致freeMemory返回的值增加。

In reference to your question, maxMemory() returns the -Xmx value. 在提到您的问题时, maxMemory()返回-Xmx值。

You may be wondering why there is a totalMemory() AND a maxMemory() . 你可能会奇怪为什么有totalMemory()maxMemory()。 The answer is that the JVM allocates memory lazily. 答案是JVM懒惰地分配内存。 Lets say you start your Java process as such: 让我们说你开始你的Java过程:

java -Xms64m -Xmx1024m Foo

Your process starts with 64mb of memory, and if and when it needs more (up to 1024m), it will allocate memory. 你的进程以64mb的内存开始,如果它需要更多(最多1024m),它将分配内存。 totalMemory() corresponds to the amount of memory currently available to the JVM for Foo. totalMemory()对应于JVM 当前可用于Foo的内存量。 If the JVM needs more memory, it will lazily allocate it up to the maximum memory. 如果JVM需要更多的内存,它会懒洋洋地分配的最大内存。 If you run with -Xms1024m -Xmx1024m , the value you get from totalMemory() and maxMemory() will be equal. 如果使用-Xms1024m -Xmx1024m运行, -Xms1024m -Xmx1024m totalMemory()maxMemory()获得的值将相等。

Also, if you want to accurately calculate the amount of used memory, you do so with the following calculation : 此外,如果要准确计算已内存量,请执行以下计算:

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

To understand it better, run this following program (in jdk1.7.x) : 要更好地理解它,请运行以下程序(在jdk1.7.x中):

 $ java -Xms1025k -Xmx1025k -XshowSettings:vm MemoryTest 

This will print jvm options and the used , free , total and maximum memory available in jvm. 这将打印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");            
        }
}

Codified version of all other answers (at the time of writing): 所有其他答案的编纂版本(撰写本文时):

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());
    }
}

Runtime#totalMemory - the memory that the JVM has allocated thus far. Runtime#totalMemory - 到目前为止JVM分配的内存。 This isn't necessarily what is in use or the maximum. 这不一定是使用中的或最大的。

Runtime#maxMemory - the maximum amount of memory that the JVM has been configured to use. Runtime#maxMemory - JVM配置使用的最大内存量。 Once your process reaches this amount, the JVM will not allocate more and instead GC much more frequently. 一旦您的流程达到此数量,JVM将不会更频繁地分配更多,而是GC。

Runtime#freeMemory - I'm not sure if this is measured from the max or the portion of the total that is unused. Runtime#freeMemory - 我不确定这是从最大值还是未使用总量的部分来衡量的。 I am guessing it is a measurement of the portion of total which is unused. 我猜测它是未使用的总量的一部分。

JVM heap size can be growable and shrinkable by the Garbage-Collection mechanism. 垃圾收集机制可以使JVM堆大小可扩展和收缩。 But, it can't allocate over maximum memory size: Runtime.maxMemory. 但是,它无法分配超过最大内存大小:Runtime.maxMemory。 This is the meaning of maximum memory. 这是最大记忆的意义。 Total memory means the allocated heap size. 总内存意味着分配的堆大小。 And free memory means the available size in total memory. 空闲内存意味着总内存中可用的大小。

example) java -Xms20M -Xmn10M -Xmx50M ~~~. 例子)java -Xms20M -Xmn10M -Xmx50M ~~~。 This means that jvm should allocate heap 20M on start(ms). 这意味着jvm应该在start(ms)上分配堆20M。 In this case, total memory is 20M. 在这种情况下,总内存为20M。 free memory is 20M-used size. 空闲内存是20M使用的大小。 If more heap is needed, JVM allocate more but can't over 50M(mx). 如果需要更多堆,JVM分配更多但不能超过50M(mx)。 In the case of maximum, total memory is 50M, and free size is 50M-used size. 在最大值的情况下,总内存为50M,自由大小为50M使用的大小。 As for minumum size(mn), if heap is not used much, jvm can shrink heap size to 10M. 至于最小大小(mn),如果堆使用不多,jvm可以将堆大小缩小到10M。

This mechanism is for efficiency of memory. 这种机制是为了提高记忆效率。 If small java program run on huge fixed size heap memory, so much memory may be wasteful. 如果小型java程序在巨大的固定大小堆内存上运行,那么大量内存可能会浪费。

You can see the results in MB format , with the division of 1024 x 1024 which is equal to 1 MB . 您可以以MB格式查看结果,分区为1024 x 1024 ,等于1 MB

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");  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM