深入淺析Java的內存機制?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
公司主營業務:成都做網站、網站制作、移動網站開發等業務。幫助企業客戶真正實現互聯網宣傳,提高企業的競爭能力。創新互聯是一支青春激揚、勤奮敬業、活力青春激揚、勤奮敬業、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰,讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創新互聯推出大通免費做網站回饋大家。
Java把內存分為兩種:一種是棧內存,另一種是堆內存。在函數中定義的一些基本類型的變量和對象的引用變量都是在函數的棧內存中分配,當在一段代碼塊定義一個變量時,Java 就在棧中為這個變量分配內存空間,當超過變量的作用域后(比如,在函數A中調用函數B,在函數B中定義變量a,變量a的作用域只是函數B,在函數B運行以后,變量a會自動被銷毀。分配給它的內存會被回收),Java會自動釋放掉為該變量分配的內存空間,該內存空間可以立即另做他用。
堆內存用來存放由new創建的內存數組,在堆中分配的內存,由Java虛擬機的自動垃圾回收器來管理。在堆中產生一個數組或對象之后,還可以在棧中定義一個特殊的變量,讓棧中的這個變量的取值等于數組或對象在堆內存中的首地址,棧中的這個變量就變成了數組或對象的引用變量,以后就可以在程序中使用棧中的變量來訪問堆中的數組或者對象,引用變量就相當于為數組或者對象起的一個名字。引用變量是普通的變量,定義時在棧中分配,引用變量在程序運行到其他作用域之外后邊釋放。而數組和對象本省在堆中分配,即使程序運行到使用new產生的數組或者對象的語句所在的代碼塊之外,數組和對象本省占據的內存不會被釋放。數組和對象在沒有引用變量指向它的時候,才變為垃圾,不能再被使用,在隨后的一個不確定時間被垃圾回收器收走(釋放掉)。這也是Java比較占內存的原因,實際上,棧中的變量指向堆內存中的變量,這就是Java中的指針。
代碼實例Demo1:單個對象創建
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年齡:"+age); } } public class Demo1 { public static void main(String[] args) { Person per = new Person() ; } }
在上述程序中實例化了一個對象per,在實例化的過程中需要再內存中開辟空間,這其中就包括棧內存和堆內存,具體的內存分配如下圖所示:
圖1-1 對象的實例化過程
我們可以從上圖中發現,對象名稱per被保存在了棧內存中(更加準確的說法是,在棧內存中保存的是堆內存空間的訪問地址),而對象的具體內容,比如屬性name和age,被保存在堆內存中。因為per對象只是被實例化,還沒有被具體賦值,所以都是默認值。字符串的默認值為null,int的類型的默認值為0。前面已經提到,堆內存空間必須使用new關鍵字才能開辟。
代碼實例Demo2:多個對象創建
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年齡:"+age); } } public class Demo2 { public static void main(String[] args) { Person per1 = new Person() ; Person per2 = new Person() ; per1.name="張三" ; per1.age=30 ; per2.age=33 ; per1.tell(); per2.tell(); } }
圖1-2 實例化兩個對象
關鍵概念:類跟數組一樣,都是屬于引用類型,引用類型就是指同一個堆內存可以被多個棧內存指向,下面來看一下引用傳遞的簡單實例。
代碼實例Demo3:對象引用傳遞1
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年齡:"+age); } } public class Demo3 { public static void main(String[] args) { Person per1 = new Person() ; Person per2 = per1 ;//-------注意-------- per1.name="張三" ; per1.age=30 ; per2.age=33 ; per1.tell(); per2.tell(); } }
程序運行結果為:
從程序的運行結果可以發現,兩個對象輸出的內容一樣,實際上所謂的引用傳遞,就是將一個堆內存空間的使用權交給多個棧內存空間,每個棧內存空間都可以修改堆內存空間的內容,此程序的內存分配圖如下所示:
圖1-3 對象引用的傳遞內存分配
圖1-3 對象引用的傳遞內存分配(續)
注意:上述實例中對象per2沒有堆內存空間,這是因為對象per2只進行聲明操作,也沒有進行實例化操作。只是使用new關鍵字,實例化以后才會有堆內存空間
代碼實例Demo4:對象引用傳遞2
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年齡:"+age); } } public class Demo4 { public static void main(String[] args) { Person per1 = new Person() ; Person per2 = new Person() ; per1.name="張三" ; per1.age=30 ; per2.name="李四" ; per2.age=33 ; per2=per1 ;//-----注意---- per1.tell(); per2.tell(); } }
上述運行程序結果為:
從程序的輸出結果可以發現跟Demo3差不多。不過內存分配發生了一些變化,具體如下所示:
圖1-4 (垃圾對象)的產生
注意點:
1.Java本身提供垃圾收集機制(Garbage Collection,GC),會不定期釋放不用的內存空間,只要對象不用了,就會等待GC釋放空間,如上面堆內存中的name="李四";age=33。
2.一個棧內存只能指向一個堆內存空間,如果要想指向其他堆內存空間,則必須先斷開已有的指向,才能分配新的指向。
Java中常見的內存區域
在Java中主要存在4塊內存空間,這些內存的名稱及作用如下:
1.棧內存空間:保存所有對象的名稱。
2.堆內存空間:保存每個對象的具體屬性內容。
3.全局數據區:保存static類型的屬性值。
4.全局代碼區:保存所有的方法定義。
看完上述內容,你們掌握深入淺析Java的內存機制的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!
網頁題目:深入淺析Java的內存機制
文章鏈接:http://www.2m8n56k.cn/article42/gpochc.html
成都網站建設公司_創新互聯,為您提供網站收錄、建站公司、關鍵詞優化、用戶體驗、Google、品牌網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯