? ? ? ? ? ? ? ? ? ? ?JAVA內(nèi)存區(qū)域與內(nèi)存溢出異常
一 Java內(nèi)存區(qū)域
? ? ? Java虛擬機(jī)在執(zhí)行java程序的過(guò)程中會(huì)把它管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域,Java虛擬機(jī)所管理的內(nèi)存包含以下幾個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)域。
? ? ?1.程序計(jì)數(shù)器
? ? ? ? ? ? ?程序計(jì)數(shù)器是一塊比較小的內(nèi)存空間,它可以看做是當(dāng)前線(xiàn)程所執(zhí)行的字節(jié)碼的行號(hào)指示器。字節(jié)碼解釋器工作就是通過(guò)改變計(jì)數(shù)器的值來(lái)選取下一條執(zhí)行的指令,分支、循環(huán)、異常處理,線(xiàn)程恢復(fù)等基礎(chǔ)功能都需要依賴(lài)計(jì)數(shù)器去完成。
? ? ? ? ? ? Java虛擬機(jī)的多線(xiàn)程是通過(guò)線(xiàn)程輪流切換并分配處理器執(zhí)行時(shí)間的方式來(lái)實(shí)現(xiàn),每條線(xiàn)程都有一個(gè)獨(dú)立的程序計(jì)算器,各個(gè)線(xiàn)程之間計(jì)數(shù)器互不影響,獨(dú)立存儲(chǔ)
? ? ?2.Java虛擬機(jī)棧
? ? ? ? ? ? a.虛擬機(jī)棧是線(xiàn)程私有的? ? b.聲明周期與線(xiàn)程一樣? c.局部變量表中可以存放各種基礎(chǔ)數(shù)據(jù)類(lèi)型,對(duì)象引用 ,其中 64位長(zhǎng)度的long和double類(lèi)型的數(shù)據(jù)占兩個(gè)局部變量空間,其他的占一個(gè),局部變量所需的內(nèi)存空間在編譯期間完成分配。 d.如果線(xiàn)程請(qǐng)求的棧深度大于虛擬機(jī)允許的深度,拋出StackOverflowError;如果虛擬機(jī)可以動(dòng)態(tài)擴(kuò)展,擴(kuò)展時(shí)沒(méi)法申請(qǐng)到足夠的內(nèi)存,拋出OutOfMemoryError.
? ? ?3.本地方法棧
? ? ? ? ? ? 與虛擬機(jī)棧的作用很相似,不過(guò)本地方法棧是為Native方法服務(wù),虛擬機(jī)棧為執(zhí)行java方法服務(wù)
? ? ?4.Java堆
? ? ? ? ? ? a.被所有線(xiàn)程共享 b.在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建 c.存放對(duì)象實(shí)例 d.堆中沒(méi)有存在完成實(shí)例分配,并且堆也無(wú)法再擴(kuò)展,拋出OutOfMemoryEoor
? ? ?5.方法區(qū)
? ? ? ? ? ?a.被所有線(xiàn)程共享 b.存放編譯器編譯后的數(shù)據(jù),類(lèi)信息,常量,靜態(tài)變量 ?c.可以不實(shí)現(xiàn)垃圾收集 ? ? d.當(dāng)方法區(qū)無(wú)法滿(mǎn)足內(nèi)存分配時(shí)拋出OutOfMemoryError
? ? ?6.常量池
常量池是方法區(qū)的一部分,Class文件中除了有類(lèi)的版本,字段,方法,接口等信息外,還有常量池,用于存在基本類(lèi)型和對(duì)象類(lèi)型、以文本形式的符號(hào)引用。比如:類(lèi)和接口的全限定名;字段和方法的名稱(chēng)與描述符;,編譯時(shí),如果發(fā)現(xiàn)對(duì)其它類(lèi)方法的調(diào)用或者對(duì)其它類(lèi)字段的引用的話(huà),記錄進(jìn)class文件中的只能是一個(gè)文本形式的符號(hào)引用,在連接過(guò)程中,虛擬機(jī)根據(jù)這個(gè)文本信息去查找對(duì)應(yīng)的方法或字段