淺談JVM與記憶體配置,淺談JVM記憶體配置
一.程式記憶體配置
初始記憶體配置
當一個程式準備運行時,它首先向java虛擬機器要記憶體,但是java虛擬機器本身沒有許可權,它只能向作業系統申請記憶體,此時java虛擬機器會擁有一個初始記憶體,
此處額外說明一下eclipse.ini檔案中的幾個參數:
-vmargs -Xms256m -Xmx512m -XX:PermSize=256M -XX:MaxPermSize=512M
-vmargs 說明後面是VM的參數,所以後面的其實都是JVM的參數了
-Xms256m JVM初始分配的堆記憶體
-Xmx512m JVM最大允許分配的堆記憶體,按需分配
-XX:PermSize=256M JVM初始分配的非堆記憶體
-XX:MaxPermSize=512M JVM最大允許分配的非堆記憶體,按需分配
然後,java虛擬機器在為程式開記憶體;當程式需要更多的空間時,假如把初始記憶體都佔用了,怎麼辦?當然啦,它會繼續向作業系統申請啊,如:
那麼問題來啦,它不可能一直申請啊?對不對,總有用完的時候,當超過堆記憶體的最大值時候,就不會再分配了,會通知記憶體溢出!
二.誰在佔用記憶體?
我相信這個圖已經能夠說明了,在jvm中有七塊記憶體地區,現在我們只討論其中的三塊,棧塊、堆塊、方法區:
棧快中儲存:對象的引用,基礎資料型別 (Elementary Data Type);
堆塊中儲存:具體對象;
方法區中:完整的類結構。
三.舉個執行個體進行分析:
person類
public class Person { public String name = null; public int age = -1; public Person() { // TODO Auto-generated constructor stub } public Person(String name, int age) { this.name = name; this.age = age; } public void showMe() { System.out.println(name + "/" + age); }}
main方法
public class PersonRun { public static void main(String[] args) { Person pj = null; pj = new Person("蒲亭", 45); pj.showMe(); Person obm = null; obm = new Person("奧巴馬", 50); obm.showMe(); int num = 10; System.out.println(num); int[] n = new int[]{1, 2, 3}; }}
記憶體配置圖:
說明:
當我們編寫一個person類時,當程式在運行時,類結構會被分配到方法區中,它只會有一份;
當我們Person pj = null;它被放在棧的地區,new Person("蒲亭", 45);它放在了堆裡,比如地址是1000d,它不會為方法再開空間,而是當我們用時會到方法中去找;
然後我們用一個引用去指向它,這樣方便使用,比如pj在棧中的地址:100z,pj儲存的是1000d地址,當我們調用showMe()方法時,先找到100z,在找到1000d,在找到方法區中的方法。
基礎資料型別 (Elementary Data Type)如 int num = 10;程式要使用它時,直接從棧中取;對於數群組類型n,它存在引用跟pj類似。