最近在網上看到一些人讨論到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