(長沙學院計算機工程與應用數(shù)學學院 長沙 410075)
Java程序中的內(nèi)存分為兩大部分:一部分叫做棧(Stack)內(nèi)存,另一部分叫堆(heap)內(nèi)存。棧內(nèi)存用來存放基本數(shù)據(jù)類型和引用數(shù)據(jù),基本數(shù)據(jù)類型如int,short,byte,f l oat等;引用數(shù)據(jù)類型如類,接口,注解等。堆內(nèi)存用來存放類中的實例化對象即用new關(guān)鍵字創(chuàng)建的對象,如 new animal(),這個數(shù)據(jù)就存放堆內(nèi)存里。通過一個簡單實例對兩部分內(nèi)存做詳細分析。[1]
上述實例中,定義了兩個基本數(shù)據(jù)類型的變量age與name;一個一般方法;在主函數(shù)內(nèi)創(chuàng)建了兩個對象。內(nèi)存分配解析如下:
棧內(nèi)存用來存放基本數(shù)據(jù)類型的變量及對象的引用地址,在實例中的基本數(shù)據(jù)類型為int age、String name; 對象的引用為 Student stu1、Student stu2.而堆內(nèi)存用來存放new出來的對象即存放上例中的new Student(8,”張三”)與new Student(12,”李四”),如圖中所示。另外,通常在堆內(nèi)存又細分出一塊內(nèi)存空間叫常量池,用來存放不常改變的量,如static修飾的量,f i nal修飾的量,字符串常量及方法,顯然,常量池里所存放的內(nèi)容具有所有實例共享的特征。實例內(nèi)存分配如圖1所示。[2]
圖1 JAVA程序內(nèi)存劃分圖
在講內(nèi)存運行機制之前,我們首先必須了解JVM即Java虛擬機,Java程序是在JVM上運行的,它是連接操作系統(tǒng)與Java程序之間的紐帶,Java程序有個特點“一次編譯,到處運行”,這正是JVM所起的作用,體現(xiàn)了Java的平臺無關(guān)性,可見,JVM在Java程序運行中起著至關(guān)重要的作用,程序的內(nèi)存分配都是在JVM中進行?,F(xiàn)結(jié)合上述簡單實例將Java的內(nèi)存運行機制講述如下:
計算機把class student整個程序信息調(diào)入計算機內(nèi)存,一旦運行程序時,JVM開始對class student整個信息進行內(nèi)存分配;
1.程序運行時,JVM自動尋找main方法,執(zhí)行第一句代碼,創(chuàng)建兩個student類的對象,在棧中分配一塊內(nèi)存,存放兩個指向堆內(nèi)存的對象指針215346和140345。
2.JVM讀到下面兩條語句時,
檢測到age,name是局部變量,因此會把age,name放在棧中,把對象指針指向堆內(nèi)存的內(nèi)容即把相應的“8,張三”與“12,李四”賦給age與name.[3]
3.當上面兩條語句執(zhí)行完了,JVM立即釋放變量ageg與name;但stu1與stu2還在堆中,并沒有釋放掉,因為可能還有其他變量指向這兩個變量。
4.JVM繼續(xù)讀取語句stu1.listening();這時從常量池中調(diào)用listening()方法給stu1對象來完成操作,JVM完成對象stu1對listening()方法的算法計算。由于listening()方法是存放于常量池中供所有類對象共享的,因此,JVM運行完語句stu1.listening()后,listening方法依舊在常量池中。
以上就是Java中內(nèi)存機制運行的介紹。
棧內(nèi)存的數(shù)據(jù)和堆內(nèi)存的數(shù)據(jù)不是同步釋放的。方法結(jié)束時,棧中的局部變量立即釋放,但是堆中對象不一定釋放。因為可能有其他變量也指向了這個對象,直到棧中沒有變量指向堆中的對象時,它才釋放,并且還不是馬上釋放,要等垃圾回收掃描時才可以被釋放。