今天在性能診斷工作中遇到 Java heap size, 下面是它的相關的概念。
- 什么是Java heap size ?
Java heap size 堆棧大小, 指Java 虛擬機的內存大小。我的理解是:在Java虛擬機中,分配多少內存用於調用對象,函數和數組。因為底層中,函數和數組的調用在計算機中是用堆棧實現的。
解釋下什么是堆棧:
堆棧是一種執行“后進先出”算法的數據結構。
設想有一個直徑不大、一端開口一端封閉的竹筒。有若干個寫有編號的小球,小球的直徑比竹筒的直徑略小。現在把不同編號的小球放到竹筒里面,可以發現一種規律:先放進去的小球只能后拿出來,反之,后放進去的小球能夠先拿出來。所以“先進后出”就是這種結構的特點。
堆棧就是這樣一種數據結構。它是在內存中開辟一個存儲區域,數據一個一個順序地存入(也就是“壓入——push”)這個區域之中。有一個地址指針總指向最后一個壓入堆棧的數據所在的數據單元,存放這個地址指針的寄存器就叫做堆棧指示器。開始放入數據的單元叫做“棧底”。數據一個一個地存入,這個過程叫做“壓棧”。在壓棧的過程中,每有一個數據壓入堆棧,就放在和前一個單元相連的后面一個單元中,堆棧指示器中的地址自動加1。讀取這些數據時,按照堆棧指示器中的地址讀取數據,堆棧指示器中的地址數自動減 1。這個過程叫做“彈出pop”。如此就實現了后進先出的原則。
(堆:累計在一起的物品,這里指的數據;棧:存放物品的倉庫或者入住的房屋,這里指的是存放數據的倉庫;數據單位:是數據傳輸的基本單位,可以看作一個整體,例如小區里面的每一棟樓,我們可以稱為1單位,2單位等)。
堆棧是計算機中最常用的一種數據結構,比如函數的調用在計算機中是用堆棧實現的。
堆棧可以用數組存儲,也可以用以后會介紹的鏈表存儲。
下面是一個堆棧的結構體定義,包括一個棧頂指針,一個數據項數組。棧頂指針最開始指向-1,然后存入數據時,棧頂指針加1,取出數據后,棧頂指針減1。
#define MAX_SIZE 100 typedef int DATA_TYPE; struct stack { DATA_TYPE data[MAX_SIZE]; int top; };
參考:http://zhidao.baidu.com/link?url=cGirpom46AiPHc_BEojGtGwnUY4WjBrw3LC0yv4t93kvngSlQpmAz11pTMTSkatbBkI16d518sGsG1wCK6cH_a
- Java heap size設置
Java 虛擬機在啟動的時候會自動設置Heap size的值,其初始空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)是物理內存的1/4。但是在實際運行中是不夠的,因為需要進行內存擴大。我們可以利用Java 虛擬機提供的-Xms -Xmx等選項可進行設置。
- 以命令行方式運行JAR包時,通過-Xms和-Xmx選項指定應用程序可使用的內存大小。其中,-Xms用於設置程序初始化時內存棧的大小,-Xmx用於設置程序可用的最大內存大小,最大不能超過1024m。例如:
java -jar jarfile.jar -Xms512m -Xmx1024m
- 在Java工程中運行時:
- 右擊要運行的文件,在彈出的菜單中選擇“Run as --> Run configruation”
- 在彈出的對話框中選擇“Arguments”標簽,然后在“VM arguments”下面的文本框中輸入初始的和最大的Heap size的大小,例如:
-Xms512m -Xmx1024m
參考:<http://163n.blog.163.com/blog/static/56035552201341831733372/>
- Java heap size 設置不合理會引發什么問題?
在JVM中如果98%的時間是用於GC且可用的 Heap size 不足2%的時候將拋出此異常信息,java.lang.OutOfMemoryError: Java heap space
如果Heap Size設置偏小,除了這些異常信息外,還會發現程序的響應速度變慢了。GC占用了更多的時間,而應用分配到的執行時間較少。
Heap size的 -Xms -Xmn 設置不要超出物理內存的大小。否則會提示“Error occurred during initialization of VM Could not reserve enough space for object heap”。