天天看點

Runtime類中的freeMemory,totalMemory,maxMemory方法,檢視記憶體情況

最近在網上看到一些人讨論到java.lang.Runtime類中的freeMemory(),totalMemory(),maxMemory ()這幾個方法的一些題目,很多人感到很迷惑,為什麼,在java程式剛剛啟動起來的時候freeMemory()這個方法傳回的隻有一兩兆位元組,而随着 java程式往前運作,建立了不少的對象,freeMemory()這個方法的傳回有時候不但沒有減少,反而會增加。

其實主要是因為這些人對freeMemory()這 個方法的意義應該有一些誤解,(今天我也遇到啦。哈哈哈)大多數人以為這個方法傳回的是操縱系統的剩餘可用記憶體,實在根本就不是這樣的。這三個方法反映的都是java這個程序的記憶體情 況,跟操縱系統的記憶體根本沒有關系。下面結合totalMemory(),maxMemory()一起來解釋。

也分享一個姑且說是整理的官方的方法文檔

https://www.yiibai.com/java/lang/runtime_freememory.html

maxMemory()

這個方法傳回的是java虛拟機(這個程序)能構從操縱系統那裡挖到的最大的記憶體,以位元組為機關,假如在運作java程 序的時 候,沒有添加-Xmx參數,那麼就是64兆,也就是說maxMemory()傳回的大約是6410241024位元組,這是java虛拟機預設情況下能 從操縱系統那裡挖到的最大的記憶體。假如添加了-Xmx參數,将以這個參數後面的值為準,例如java -cp ClassPath -Xmx512m ClassName,那麼最大記憶體就是51210240124位元組。

totalMemory()

這個方法傳回的是java虛拟機現在已經從操縱系統那裡挖過來的記憶體大小,也就是java虛拟機這個程序當時所占用的 所有 記憶體。假如在運作java的時候沒有添加-Xms參數,那麼,在java程式運作的過程的,記憶體總是慢慢的從操縱系統那裡挖的,基本上是用多少挖多少,直 挖到maxMemory()為止,是以totalMemory()是慢慢增大的。假如用了-Xms參數,程式在啟動的時候就會無條件的從操縱系統中挖- Xms後面定義的記憶體數,然後在這些記憶體用的差未幾的時候,再往挖。

freeMemory()

是什麼呢,剛才講到假如在運作java的時候沒有添加-Xms參數,那麼,在java程式運作的過程的,記憶體總是慢慢的 從操 作系統那裡挖的,基本上是用多少挖多少,但是java虛拟機100%的情況下是會稍微多挖一點的,這些挖過來而又沒有用上的記憶體,實際上就是 freeMemory(),是以freeMemory()的值一般情況下都是很小的,但是假如你在運作java程式的時候使用了-Xms,這個時候由于程 序在啟動的時候就會無條件的從操縱系統中挖-Xms後面定義的記憶體數,這個時候,挖過來的記憶體可能大部分沒用上,是以這個時候freeMemory()可 能會有些大。

availableProcessors()

方法傳回到Java虛拟機的可用的處理器數量。此值可能會改變在一個特定的虛拟機調用。應用程式可用處理器的數量是敏感的,是以偶爾查詢該屬性,并适當地調整自己的資源使用情況.

此方法傳回到虛拟機的最大可用的處理器數量;決不會小于一個

把下面的源代碼編譯以後,在class檔案所在的目錄裡面,分别用java -cp . Untitled1 和java -cp . -Xms80m -Xmx80m Untitled1 運作,看看結果如何,有助于了解上面的闡述。

public class Untitled1 {      
      public Untitled1() {}      
      public static void main(String[] args) {  
        System.out.println(Runtime.getRuntime().freeMemory());  
        System.out.println(Runtime.getRuntime().totalMemory());  
        System.out.println(Runtime.getRuntime().maxMemory());  
        long t = System.currentTimeMillis();  
        try {  
          Thread.sleep(30000);  
       } catch (Exception ee) {  
         ee.printStackTrace();  
       }  
       String[] aaa = new String[2000000];  
       System.out.println(Runtime.getRuntime().freeMemory());  
       System.out.println(Runtime.getRuntime().totalMemory());  
       System.out.println(Runtime.getRuntime().maxMemory());  
       try {  
         Thread.sleep(30000);  
       } catch (Exception ee) {  
         ee.printStackTrace();  
       }  
       for (int i = 0; i < 2000000; i++) {  
         aaa[i] = new String("aaa");  
       }  
       System.out.println(Runtime.getRuntime().freeMemory());  
       System.out.println(Runtime.getRuntime().totalMemory());  
       System.out.println(Runtime.getRuntime().maxMemory());  
       try {  
         Thread.sleep(30000);  
       } catch (Exception ee) {  
         ee.printStackTrace();  
       }  
     }  
   } 
           

以上部分整理轉自:http://wenku.baidu.com/link?url=hXtN8gFyOn4c-J7vkW-YKO1Hq4dgKYkwCIdE3s3BzwG6ZqwDAKyZ8-ZhlmOz_fDPAQaWjqPUZ544G5C-nfjJnAinS-pKaeZJJBFTCvrqAkq

簡單的說就是

maxMemory 就是一次擷取的上限值

totalMemory就是分批次擷取,每一次的上限值

freeMemory每一次消耗過後的剩餘值

很簡單的案例

public static void getJvmData(){
        // 得到JVM中的空閑記憶體量(機關是位元組)
        System.out.println("--得到JVM中的空閑記憶體量" + Runtime.getRuntime().freeMemory());
        // 已配置設定到的JVM記憶體總量(機關是位元組)
        System.out.println( "--已配置設定到的JVM記憶體總量" + Runtime.getRuntime().totalMemory());
        // JVM試圖使用額最大記憶體量(機關是位元組)
        System.out.println( "--JVM試圖使用額最大記憶體量" + Runtime.getRuntime().maxMemory());
        // 可用處理器的數目
        System.out.println( "--可用處理器的數目" + Runtime.getRuntime().availableProcessors());
    }
           

今天想起來分析記憶體的方法是因為是在項目導入excal的時候,使用的poi處理引起的OOM報錯,才關系到這次的文章内容。

同時也給大家分享另外一個東西 EasyExcal 遠比poi要好用很多。當然也是阿裡的。

詳細分析以及

poi讀取excel資料方法和EasyExcal讀取表格資料方法比較

https://blog.csdn.net/qq_34129814/article/details/118122945