學(xué)習(xí)Java語言需要學(xué)習(xí)一些和Java相關(guān)的底層原理,這將有利之后對(duì)于Java代碼的理解和使用。本文將著重介紹Java中的JVM和堆棧內(nèi)存的概念和區(qū)別。
JVM
JVM(全稱Java Virtual Machine),也就是Java虛擬機(jī)。
Java程序在運(yùn)行的時(shí)候都要開辟一個(gè)空間,也就是說任何軟件在運(yùn)行的時(shí)候都需要開辟空間,同樣JVM也不例外,也需要開辟空間。JVM運(yùn)行時(shí)在內(nèi)存中開辟的內(nèi)存區(qū)域,啟動(dòng)時(shí)在這片區(qū)域內(nèi)自己還會(huì)進(jìn)行更細(xì)致的劃分,因?yàn)樘摂M機(jī)中每片內(nèi)存處理的方式都不一樣,所以要分別單獨(dú)進(jìn)行管理。
JVM內(nèi)存的劃分主要是下列五個(gè):
- 寄存器
- 本地方法去
- 方法區(qū)
- 棧內(nèi)存
- 堆內(nèi)存
棧內(nèi)存
棧內(nèi)存里面存儲(chǔ)的都是局部變量。
什么是局部變量?凡是定義在方法中的都是局部變量,for循環(huán)內(nèi)定義的也是局部變量。
先加載函數(shù)才能進(jìn)行局部變量的定義,所以在方法進(jìn)棧后,然后再定義變量,變量是有自己的作用域,一旦離開這個(gè)作用域,變量就會(huì)馬上被釋放。也因此,棧內(nèi)存的更新速度非???,這也是因?yàn)榫植孔兞康纳芷诙己芏獭?/p>
堆內(nèi)存
new
?建立的都是在堆中,堆中存放的都是實(shí)體(也就是對(duì)象)。int[] arr = new int[3];
?在內(nèi)存中是怎樣被定義的?arr
?的變量,但右邊不是一個(gè)具體值,是一個(gè)實(shí)體。new
?開辟了空間。內(nèi)存在存儲(chǔ)數(shù)據(jù)的時(shí)候,都是通過地址值來體現(xiàn)的,地址值是一塊連續(xù)的二進(jìn)制,然后給這個(gè)實(shí)體分配了一個(gè)內(nèi)存地址。那么棧內(nèi)存和堆內(nèi)存要怎么聯(lián)系起來?
前文提到,每個(gè)實(shí)體進(jìn)入堆內(nèi)存后,都被分配一個(gè)內(nèi)存地址。把這個(gè)內(nèi)存地址賦給變量?arr
?,?arr
?就可以通過地址找到數(shù)組。所以?arr
?想要操縱數(shù)組,就得通過地址,而不是直接把實(shí)體都賦給它。所以,這種我們不再稱呼為基本數(shù)據(jù)類型,而是引用數(shù)據(jù)類型,稱為?arr
?引用了堆內(nèi)存當(dāng)中的實(shí)體。
如果當(dāng) ?int[] arr = null;
?
?arr
?不做任何指向,?null
?的作用就是取消引用數(shù)據(jù)類型的指向。
當(dāng)一個(gè)實(shí)體沒有引用數(shù)據(jù)類型指向的時(shí)候,是不會(huì)被釋放掉,而是會(huì)被當(dāng)做垃圾。
Java有一個(gè)自動(dòng)回收機(jī)制,會(huì)自動(dòng)檢測(cè)堆里是否存有垃圾,如果有,那么就會(huì)回收垃圾,但是至于什么時(shí)候回收就不一定了。
堆內(nèi)存和棧內(nèi)存的區(qū)別
通過以上內(nèi)容,可以得出以下幾點(diǎn)不同:
- 棧內(nèi)存存儲(chǔ)的是局部變量;堆內(nèi)存存儲(chǔ)的是實(shí)體。
- 棧內(nèi)存的更新速度要快于堆內(nèi)存,是因?yàn)榫植孔兞康纳芷诙獭?/li>
- 棧內(nèi)存存放的變量一旦結(jié)束就會(huì)釋放;堆內(nèi)存存放的實(shí)體會(huì)被垃圾回收機(jī)制不定時(shí)回收。