JAVA內存點滴

原文地址:http://wubolu.iteye.com/blog/1770810
JVM啓動以後,會分配兩類內存區域,一類用於開發職員使用,比如保存一些變量,對象等,一類JVM自己使用,比如存放一些class類和描述。

供開發使用的內存

第一類內存區域又可以分爲棧(stack)、堆(heap),還有一些靜態存儲區域,這部分的內存在JVM啓動的時候,可以用參數進行配置:
-Xms 初始堆大小,這個值不能太小,其初始空間(即-Xms)是物理內存的1/64,這個值不能太小,比如 設置了-Xms1m,運行可能會出現

Error occurred during initialization of VM
Too small initial heap for new size specified

-Xmx 堆大小上限,最大空間(-Xmx)是物理內存的1/4,假如程序中分配的內存超過了這個限制,那麼會出現

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

代碼爲:

byte[] b = new byte[100000000];

-Xss 線程棧大小,一般不用設置,JDK5.0以後每個線程堆棧大小爲1M,以前每個線程堆棧大小爲256K。更具應用的線程所需內存大小進行調整。有時候會發現一下異常,

Exception in thread "main" java.lang.StackOverflowError

原因一般是:

public static int callMyself(){
return callMyself();
}

方法的遞迴或者死循環,導致棧空間不夠用了。

棧和堆到底存些什麼,很多地方都有講到,這裏參考下《Think in java》的,棧裏存放對象引用、基本類型的變量等,而堆裏面存放對象和數組。方法的執行是在棧上進行的,這一點可以通過異常的時候,經常會默認打印

e.printStackTrace();

棧信息得知。

Runtime類有幾個函數,我們可以簡單的通過這幾個函數,看看JVM中的一些內存信息。

maxMemory()這個方法返回的是java虛擬機(這個進程)能構從操縱系統那裏挖到的最大的內存,以字節爲單位,假如在運行java程序的時 候,沒有添加-Xmx參數,那麼就是64兆,也就是說maxMemory()返回的大約是64*1024*1024字節,這是java虛擬機默認情況下能 從操縱系統那裏挖到的最大的內存。假如添加了-Xmx參數,將以這個參數後面的值爲準,例如java -cp ClassPath -Xmx512m ClassName,那麼最大內存就是512*1024*0124字節。

totalMemory()這個方法返回的是java虛擬機現在已經從操縱系統那裏挖過來的內存大小,也就是java虛擬機這個進程當時所佔用的所有 內存。假如在運行java的時候沒有添加-Xms參數,那麼,在java程序運行的過程的,內存總是慢慢的從操縱系統那裏挖的,基本上是用多少挖多少,直 挖到maxMemory()爲止,所以totalMemory()是慢慢增大的。假如用了-Xms參數,程序在啓動的時候就會無條件的從操縱系統中挖- Xms後面定義的內存數,然後在這些內存用的差未幾的時候,再往挖。

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

下面我們來看看例子:

Runtime rt = Runtime.getRuntime();


info("Max   memory: " + rt.maxMemory());

long fisrt = rt.freeMemory();

info("Total memory: " + rt.totalMemory());

info("Free memory: " + fisrt);



int size = 10000;



byte[] b = new byte[size];

long bL = rt.freeMemory();

info("Free memory: " + bL);

info("byte allocate Cost memory: " + (fisrt - bL) + ", Array size :" + size);

運行參數爲 -Xms8m -Xmx32m (太大了可能看不出來),運行結果爲:

2011-02-22 10:28:01: Max   memory: 33357824

2011-02-22 10:28:01: Total memory: 8323072

2011-02-22 10:28:01: Free memory: 7791752

2011-02-22 10:28:01: Free memory: 7781736

2011-02-22 10:28:01: byte allocate Cost memory: 10016, Array size :10000

33357824 <> 32*1025*1024(大約即是)

8323072 <> 8×1024×1024

最後看看10000長度的byte數組,分配了多少內存,大約爲10016,這說明除了10000個大小爲1字節的byte以外,還有16個字節其他的玩意。

將byte換成int(4字節):

2011-02-22 10:35:21: int allocate Cost memory: 40016, Array size :10000

與byte相同,也是4*10000+16
將byte換成long(8字節):

2011-02-22 10:32:47: long allocate Cost memory: 80016, Array size :10000

與byte相同,也是8*10000+16

再看看String數組:

2011-02-22 10:34:40: String allocate Cost memory: 40016, Array size :10000

String作爲一個對象,分配的內存大小與int相同,說明了這臺機器是32(4*8)位的

最後看看Object對象,

2011-02-22 10:37:02: Object allocate Cost memory: 40016, Array size :10000

與String一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章