java你可能不知道的事(2)


在java語言的學習和使用當中你可能已經了解或者知道堆和棧,但是你可能沒有完全的理解它們。今天我們就一起來學習堆、棧的特點以及它們的區別。認識了這個之后,你可能對java有更深的理解。

Java堆內存(Heap Memory)

堆內存在Java運行時主要去回收對象和JRE的類。當我們創建了一個對象(也就是 new一個對象),在堆內存就會為對象分配一個空間,Java垃圾回收器(GC)運行在堆內存里,一旦發現沒有任何地方引用到這個對象,就釋放這個對象所占的內存。 
被創建的對象存在於堆內存,並且擁有全局權限,能被應用的任何地方引用到。

Java棧內存(Stack Memory)

堆內存是單線程執行的,它的空間比堆內存空間要小。它里面會包括定義在方法里的、短時間存在的局部變量,這些局部變量總是引用到堆內存的對象。堆內存還有個特點就是后進先出。當一個方法被調用之后,在棧內存就會為這個方法產生一個內存區域來保存方法里的基本數據類型數據和引用了堆內存中對象的局部變量。當這個方法執行完畢,這個塊沒有用了,就會被垃圾回收器回收,接着繼續下一個方法。

加深理解

先來看一段簡單的代碼

 1 public class TestMemory {
2
3 public static void main(String[] args) {
4 int i = 666;//line1
5 Object object = new Object();//line2
6 TestMemory testMemory = new TestMemory();//line3
7 testMemory.test(object);//line4
8 }
9 //line5
10 private void test(Object params){//line6
11 String str = params.toString();//line7
12 System.out.println(str);//line8
13 }
14 }
15 //line9

 

下面這張圖片展示了上面代碼的內存信息。

這里寫圖片描述

1、當程序運行時,JVM會先加載運行時的類和我們自己寫的類信息,這些類信息加載后存在堆內存當中。

2、接着進入到main方法,第一行line1創建了一個基本數據類型i=666,所以創建了一個main方法的內存塊,它里面同時存放了i=666;

3、接着line2和line3的位置 
Object object = new Object(); 
TestMemory testMemory = new TestMemory();創建了兩個局部變量,object和testMemory,同時在堆里存放了兩個新的對象Object和TestMemory。(每次我們new 一個對象都會在堆區產生一塊內存區給它分配空間)。同時object和testMemory引用了new出來的對象。

4、現在到了line4,test方法了,當調用到test方法的時候,在棧的頂層創建了一塊test()方法的內存區(我們說過棧的特點就是后進先出),由於在 Java里的傳遞是值傳遞,所以就有了參數object產生了一個新的引用。

5、最后調用了toString產生了一個字符串常量存放在了String pool里,並且str 引用了它。(如果你有String類感興趣,你可能喜歡 》 Java你可能不知道的事系列1_String類

6、當test方法結束,它里面的變量也就被GC回收掉了。接着main方法也就結束。Java在運行時釋放這些內存並結束程序的運行。

總結

1、當一個對象被創建,總是會在堆內存為它分配空間並且存儲,如果有賦值就會將變量引用到對象。而棧內存就是存放這些引用對象的局部變量。

2、棧內存的生命周期很短,而堆內存從程序執行開始到結束一只都需要工作。因為棧內存沒當執行完一個方法,它們所占的內存區就會被釋放。而堆內存里的對象只有在沒有任何變量引用到它的時候才可能會被釋放。

3、棧內存大小相比於堆內存非常小。但是它相對於堆內存又比較快。

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com