Runtime.getRuntime (). TotalMemory () ve freeMemory () nedir?


Yanıtlar:


195

API'ya göre

totalMemory()

Java sanal makinesindeki toplam bellek miktarını döndürür. Bu yöntemle döndürülen değer, ana bilgisayar ortamına bağlı olarak zaman içinde değişebilir. Herhangi bir türde bir nesneyi tutmak için gereken bellek miktarının uygulamaya bağlı olabileceğini unutmayın.

maxMemory()

Java sanal makinesinin kullanmaya çalışacağı maksimum bellek miktarını döndürür. İçsel bir sınır yoksa, Long.MAX_VALUE değeri döndürülür.

freeMemory()

Java Sanal Makinesi'ndeki boş bellek miktarını döndürür. Gc yönteminin çağrılması, freeMemory tarafından döndürülen değerin artmasına neden olabilir.

Sorunuzla ilgili olarak maxMemory(), -Xmxdeğeri döndürür .

Neden bir totalMemory () VE bir maxMemory () olduğunu merak ediyor olabilirsiniz . Cevap JVM'nin hafızayı tembel olarak ayırmasıdır. Diyelim ki Java işleminizi şu şekilde başlattınız:

java -Xms64m -Xmx1024m Foo

İşleminiz 64mb bellek ile başlar ve daha fazla (1024m'ye kadar) ihtiyaç duyuyorsa ve gerekiyorsa, bellek ayırır. şu anda Foo için JVM tarafından kullanılabilen totalMemory()bellek miktarına karşılık gelmektedir . JVM daha fazla bellek ihtiyacı varsa, o tembel bunu tahsis edecek kadar maksimum bellek. İle koşarsanız , aldığınız ve eşit olacak değer .-Xms1024m -Xmx1024mtotalMemory()maxMemory()

Ayrıca, kullanılan bellek miktarını doğru bir şekilde hesaplamak istiyorsanız , bunu aşağıdaki hesaplama ile yaparsınız:

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

-XmxDeğeri ile doğrudan başlangıç etkiler gibi görünüyor maxMemory()I bildirilen gördük ancak değeri maxMemory(), belki de ~% 1 küçük bir miktar artış programı çalışırken,.
H2ONaCl

2
Bunun farkı Debug.getNativeHeapFreeSize()nedir?
IgorGanapolsky

@ H2ONaCl evet, biraz değişebilir, çünkü JVM'ler UseAdaptiveSizePolicyvarsayılan olarak etkindir. Ve BTW: maxMemory()= Xmx- tek bir hayatta kalan alanın büyüklüğü. Neden? Çünkü aynı zamanda, yalnızca bir hayatta kalan alan kullanılabilir.
G. Demecki

236

İsimler ve değerler kafa karıştırıcı. Toplam boş hafıza arıyorsanız, bu değeri kendiniz hesaplamanız gerekir. O değil sen ne olsun freeMemory();.

Aşağıdaki kılavuza bakın:

Toplam atanmış bellek , bu yapılandırılmış -Xmx değerine eşit olacaktır :

Runtime.getRuntime () maxMemory (.);

Mevcut tahsisli boş bellek , yeni nesneler için hazır olan mevcut tahsis edilen alandır . Dikkat, bu toplam kullanılabilir boş bellek değildir:

Runtime.getRuntime () freeMemory (.);

Toplam bellek tahsis toplam ayrılan alandır, ayrılmış java işlemi için:

Runtime.getRuntime () totalMemory (.);

Kullanılan bellek , hesaplanmalıdır:

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

Toplam boş hafıza , hesaplanmalıdır:

freeMemory = Runtime.getRuntime (). maxMemory () - kullanılmışMemory;

Bir resim netleştirmeye yardımcı olabilir:

java çalışma zamanı belleği


1
Bu farklı mı Debug.getMemoryInfo()?
IgorGanapolsky

1
Not: Kullanılmış bellek olabilir artık başvurulan nesneleri içerir sonraki GC ile süpürülüp edilecektir.
Gab 是 好人

@cheneym, java bayt kodu talimatları yalnızca "Xmx - Usedmemory" makinede avlbl ise işlemci tarafından işleneceğinden, boş ve boş bellek işgal edilecektir. Xmx, makinenin kendisinde avlbl havadan gelen hava ile doldurulabilecek maksimum ballon kapasitesi gibidir, hava alır almaz, doldurulur ve Xmx sınırını aştığında patlar. Ama toplam freememory JVM için makinedeki gerçek avbl belleği anlatmayacak, ama sadece nmbr.Is orada Rqd belleğin JVM remaning için avlbl olup olmadığını öğrenmek için makine gerçek avlbl bellek bulmak için herhangi bir yolu süreç?
Maria

12

Daha iyi anlamak için, aşağıdaki programı çalıştırın (jdk1.7.x dosyasında):

$ java -Xms1025k -Xmx1025k -XshowSettings:vm  MemoryTest

Bu, jvm seçeneklerini ve kullanılan , ücretsiz , toplam ve maksimum belleği jvm olarak basacaktır.

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

Diğer tüm cevapların kodlanmış versiyonu (yazma sırasında):

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

Çalışma zamanı # totalMemory - JVM'nin şu ana kadar ayırdığı bellek. Kullanımda olan veya maksimum olan bu olmak zorunda değildir.

Çalışma zamanı # maxMemory - JVM'nin kullanmak için yapılandırıldığı maksimum bellek miktarı. İşleminiz bu miktara ulaştığında, JVM daha fazla ayırmayacak, bunun yerine GC'yi daha sık tahsis edecektir.

Çalışma zamanı # freeMemory - Bunun maksimumdan veya toplamın kullanılmayan kısımdan ölçüldüğünden emin değilim. Sanırım toplamın kullanılmayan kısmının bir ölçümü.


5

JVM yığın boyutu, Çöp Toplama mekanizması ile büyütülebilir ve küçültülebilir. Ancak, maksimum bellek boyutu üzerinden ayrılamaz: Runtime.maxMemory. Maksimum hafızanın anlamı budur. Toplam bellek, ayrılan yığın boyutu anlamına gelir. Ve boş hafıza, toplam hafızadaki kullanılabilir boyut anlamına gelir.

örnek) java -Xms20M -Xmn10M -Xmx50M ~~~. Bu, jvm'nin yığın (20M) üzerinde başlangıç ​​(ms) ayırması gerektiği anlamına gelir. Bu durumda, toplam bellek 20M'dir. boş bellek 20M kullanılan boyuttadır. Daha fazla yığın gerekiyorsa, JVM daha fazla ayırır ancak 50M (mx) üzerinde olamaz. Maksimum durumda, toplam bellek 50M ve boş boyut 50M kullanılan boyuttur. Minumum boyuta (mn) gelince, yığın çok kullanılmazsa, jvm yığın boyutunu 10M'ye küçültebilir.

Bu mekanizma hafızanın verimliliği içindir. Küçük java programı büyük sabit boyutlu yığın bellek üzerinde çalışırsa, çok fazla bellek israf olabilir.


1

Sonuçları 1 MB'ye eşit olan 1024 x 1024 bölünmeyle MB biçiminde görebilirsiniz .

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");  
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.