Runtime.getRuntime (). totalMemory () 및 freeMemory () 란 무엇입니까?


답변:


195

API 에 따르면

totalMemory()

Java 가상 머신의 총 메모리 양을 리턴합니다. 이 방법으로 반환되는 값은 호스트 환경에 따라 시간이 지남에 따라 달라질 수 있습니다. 주어진 유형의 객체를 보유하는 데 필요한 메모리 양은 구현에 따라 다를 수 있습니다.

maxMemory()

Java 가상 머신이 사용하려고하는 최대 메모리 양을 리턴합니다. 고유 제한이 없으면 Long.MAX_VALUE 값이 반환됩니다.

freeMemory()

JVM (Java Virtual Machine)에서 사용 가능한 메모리 양을 리턴합니다. gc 메소드를 호출하면 freeMemory에서 리턴 한 값이 증가 할 수 있습니다.

질문과 관련 maxMemory()하여 -Xmx값을 반환합니다 .

totalMemory ()maxMemory () 가 왜 있는지 궁금 할 것 입니다. 대답은 JVM이 느리게 메모리를 할당한다는 것입니다. 다음과 같이 Java 프로세스를 시작한다고 가정하십시오.

java -Xms64m -Xmx1024m Foo

프로세스는 64MB의 메모리로 시작하며 더 많은 양이 필요할 때 (최대 1024m) 메모리를 할당합니다. JVM for Foo에서 현재 사용 가능한 totalMemory()메모리 양에 해당합니다 . JVM에 더 많은 메모리가 필요한 경우 최대 메모리 까지 느리게 할당합니다 . 당신이 실행하는 경우 , 당신은에서 얻을 값 과 동일 할 것이다.-Xms1024m -Xmx1024mtotalMemory()maxMemory()

또한 사용 된 메모리 의 양을 정확하게 계산 하려면 다음 계산을 수행하십시오.

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

-Xmx값은 초기 maxMemory()값 에 직접 영향을 미치는 것처럼 보이지만 maxMemory()프로그램이 실행되는 동안 소량 증가 했을 것으로 예상됩니다 (약 1 %).
H2ONaCl

2
이것과 어떻게 Debug.getNativeHeapFreeSize()다릅니 까?
IgorGanapolsky

@ H2ONaCl 예, JVM UseAdaptiveSizePolicy이 기본적으로 활성화되어 있기 때문에 약간 변경 될 수 있습니다 . 그리고 BTW : maxMemory()= Xmx-단일 생존자 공간의 크기. 왜? 동시에 하나의 생존자 공간 만 사용할 수 있기 때문입니다.
G. Demecki

236

이름과 값이 혼동됩니다. 사용 가능한 총 메모리 를 찾고 있다면 이 값을 스스로 계산해야합니다. 그것은 당신이 얻는 것이 아닙니다freeMemory(); .

다음 안내서를 참조하십시오.

지정된 총 메모리 . 구성된 -Xmx 값과 같습니다.

Runtime.getRuntime (). maxMemory ();

현재 할당 된 여유 메모리 는 새 객체를 위해 준비된 현재 할당 된 공간 입니다. 주의 이것은 사용 가능한 총 여유 메모리 가 아닙니다 .

Runtime.getRuntime (). freeMemory ();

총 할당 메모리 는 Java 프로세스를 위해 예약 된 총 할당 공간입니다 .

Runtime.getRuntime (). totalMemory ();

사용한 메모리 는 다음과 같이 계산되어야합니다.

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

사용 가능한 총 메모리 는 다음과 같이 계산해야합니다.

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

사진은 다음을 명확히하는 데 도움이 될 수 있습니다.

자바 런타임 메모리


1
와 다른가요 Debug.getMemoryInfo()?
IgorGanapolsky

1
참고 : 사용 된 메모리 에는 다음 GC에 의해 스윕 될 더 이상 참조 된 오브젝트 포함되지 않을 있습니다 .
Gab 是 好人

@cheneym, 비어 있고 할당되지 않은 메모리는 시스템에서 "Xmx-Usedmemory"가 avlbl 인 경우에만 프로세서에서 Java 바이트 코드 명령어를 처리하므로 사용되지 않는 메모리와 사용되지 않은 메모리가 사용됩니다. Xmx는 기계 자체의 avlbl 공기에서 나오는 공기로 채울 수있는 ballon의 최대 용량과 같습니다. 공기가 들어 오면 채워지고 Xmx 한도를 초과하면 폭발합니다. 그러나 총 freememory는 JVM의 컴퓨터에서 실제 avbl 메모리를 알려주지 않지만 nmbr 만 있습니다 .rqd 메모리가 avlbl인지 JVM remaning인지 알 수 있도록 컴퓨터의 실제 avlbl 메모리를 찾을 수있는 방법 프로세스?
마리아

12

더 잘 이해하려면 다음 프로그램을 실행하십시오 (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");            
        }
}

8

다른 모든 답변의 체계화 된 버전 (작성 당시) :

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

7

런타임 #totalMemory -JVM이 지금까지 할당 한 메모리 이것이 반드시 사용중인 것이거나 최대 값 인 것은 아닙니다.

런타임 #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 프로그램이 거대한 고정 크기 힙 메모리에서 실행되면 많은 메모리가 낭비 될 수 있습니다.


1

사용자는 결과에서 볼 수있는 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");  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.