這篇文章主要介紹“Java中JVM、堆內存和棧內存的概念和區別是什么”,在日常操作中,相信很多人在Java中JVM、堆內存和棧內存的概念和區別是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中JVM、堆內存和棧內存的概念和區別是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
JVM(全稱Java Virtual Machine),也就是Java虛擬機。
Java程序在運行的時候都要開辟一個空間,也就是說任何軟件在運行的時候都需要開辟空間,同樣JVM也不例外,也需要開辟空間。JVM運行時在內存中開辟的內存區域,啟動時在這片區域內自己還會進行更細致的劃分,因為虛擬機中每片內存處理的方式都不一樣,所以要分別單獨進行管理。
JVM內存的劃分主要是下列五個:
寄存器
本地方法去
方法區
棧內存
堆內存
棧內存里面存儲的都是局部變量。
什么是局部變量?凡是定義在方法中的都是局部變量,for循環內定義的也是局部變量。
先加載函數才能進行局部變量的定義,所以在方法進棧后,然后再定義變量,變量是有自己的作用域,一旦離開這個作用域,變量就會馬上被釋放。也因此,棧內存的更新速度非???,這也是因為局部變量的生命周期都很短。
堆內存里面存儲的是數組和對象。(數組也算是對象的一種。)
什么是對象?凡是new
建立的都是在堆中,堆中存放的都是實體(也就是對象)。
實體用于封裝數據,而是封裝了多個,如果一個數據消失,這個實體卻沒消失,則還可以使用。所以堆是不會隨時釋放的,但是棧就不一樣了,棧里面存放的都是單個變量,變量被釋放了,就消失了。堆里的實體雖然不會被釋放,但會被Java垃圾回收機制當做垃圾不定時的收取。
例子:
int[] arr = new int[3];
在內存中是怎樣被定義的?
如圖所示,主函數首先進入了棧中,在棧中定義了一個arr
的變量,但右邊不是一個具體值,是一個實體。
實體是被創建在堆內存里面的,在堆里面首先通過new
開辟了空間。內存在存儲數據的時候,都是通過地址值來體現的,地址值是一塊連續的二進制,然后給這個實體分配了一個內存地址。
數組都是有一個索引,數組這個實體在堆內存中產生后每一個空間都會進行默認的初始化,不同的類型初始化的值不一樣。
所以在棧和堆當中分別創建了變量和實體。
那么棧內存和堆內存要怎么聯系起來?
前文提到,每個實體進入堆內存后,都被分配一個內存地址。把這個內存地址賦給變量arr
,arr
就可以通過地址找到數組。所以arr
想要操縱數組,就得通過地址,而不是直接把實體都賦給它。所以,這種我們不再稱呼為基本數據類型,而是引用數據類型,稱為arr
引用了堆內存當中的實體。
如果當 int[] arr = null;
arr
不做任何指向,null
的作用就是取消引用數據類型的指向。
當一個實體沒有引用數據類型指向的時候,是不會被釋放掉,而是會被當做垃圾。
Java有一個自動回收機制,會自動檢測堆里是否存有垃圾,如果有,那么就會回收垃圾,但是至于什么時候回收就不一定了。
通過以上內容,可以得出以下幾點不同:
棧內存存儲的是局部變量;堆內存存儲的是實體。
棧內存的更新速度要快于堆內存,是因為局部變量的生命周期短。
棧內存存放的變量一旦結束就會釋放;堆內存存放的實體會被垃圾回收機制不定時回收。
到此,關于“Java中JVM、堆內存和棧內存的概念和區別是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。