The PRocess Memory: 除了SGA(System Global Area)之外,Oracle進(jìn)程還使用下面三個(gè)全局區(qū):The Process Global Area (PGA)The User Global Area (UGA)The Call Global Area (CGA) 很多人都搞不清楚PGA和UGA兩者之間的區(qū)別,實(shí)際上兩者之間的區(qū)別跟一個(gè)進(jìn)程和一個(gè)會(huì)話之間的區(qū)別是類似的.盡管說(shuō)進(jìn)程和會(huì)話之間一般都是一對(duì)一的關(guān)系,但實(shí)際上比這個(gè)更復(fù)雜.一個(gè)很明顯的情況是MTS配置,會(huì)話往往會(huì)比進(jìn)程多得多.在這種配置下,每一個(gè)進(jìn)程會(huì)有一個(gè)PGA,每一個(gè)會(huì)話會(huì)有一個(gè)UGA.PGA所包含的信息跟會(huì)話是無(wú)任何關(guān)聯(lián)的,而UGA包含的信息是以特定的會(huì)話為基礎(chǔ)的. The PGA:進(jìn)程全局區(qū)(PGA)即可以理解為Process Global Area,也可以理解為Program Global Area.它的內(nèi)存段是在進(jìn)程私有區(qū)(Process Private Memory)而不是在共享區(qū)(Shared Memory).它是個(gè)全局區(qū)意味著它包含了所有代碼有可能進(jìn)入的全局變量和數(shù)據(jù)結(jié)構(gòu),但是它是不被所有進(jìn)程共享的.每個(gè)Oracle的服務(wù)器進(jìn)程都包含有屬于自己的PGA,它只包含了本進(jìn)程的相關(guān)特定信息.PGA中的結(jié)構(gòu)不需要由latches來(lái)保護(hù),因?yàn)槠渌倪M(jìn)程是不能進(jìn)入到這里面來(lái)訪問(wèn)的.PGA包含的是有關(guān)進(jìn)程正在使用的操作系統(tǒng)資源信息以及進(jìn)程的狀態(tài)信息,而其它的進(jìn)程所使用的Oracle的共享資源是在SGA中.PGA是私有的而不是共享的,這個(gè)機(jī)制是有必要的,因?yàn)楫?dāng)進(jìn)程死掉后可以把這些資源清除和釋放掉.PGA包含兩個(gè)主要區(qū)域:Fixed PGA和Variable PGA或稱為PGA Heap. Fixed PGA的作用跟Fixed SGA是類似的,都包含原子變量(不可分的),小的數(shù)據(jù)結(jié)構(gòu)和指向Variable PGA的指針.Variable PGA是一個(gè)堆.它的Chunks可以從Fixed Table X$KSMPP查看得到,這個(gè)表的結(jié)構(gòu)跟前面有提到的X$KSMSP是相同的.PGA HEAP包含了一些有關(guān)Fixed Table的永久性內(nèi)存,它跟某些參數(shù)的設(shè)置有依靠關(guān)系.這些參數(shù)包含DB_FILES,LOG_FILES,CONTROL_FILES. The UGA: UGA(User Global Area)包含的是特定會(huì)話的信息,有如下一些: 所打開(kāi)游標(biāo)的持續(xù)和運(yùn)行時(shí)間內(nèi)的區(qū)域 包的狀態(tài)信息,特定的變量 java會(huì)話狀態(tài) 可以用的ROLES 被ENABLE的跟蹤事件 起作用的NLS參數(shù)設(shè)置 打開(kāi)的DBLINK 會(huì)話的入口控制 跟PGA一樣,UGA也由兩區(qū)組成:Fixed UGA和Variable UGA,也稱為UGA HEAP. Fixed UGA包含了大約70個(gè)原子變量,小的數(shù)據(jù)結(jié)構(gòu)和指向Variable UGA的指針. UGA HEAP中的Chunks可以從它們自己的會(huì)話中通過(guò)查看表X$KSMUP獲得相關(guān)信息,這個(gè)表的結(jié)構(gòu)跟X$KSMSP是一樣的.UGA HEAP包含了一些有關(guān)fixed tables的永久性內(nèi)存段,跟一些參數(shù)的設(shè)置有依靠關(guān)系.這些參數(shù)有OPEN_CURSORS,OPEN_LINKS,和MAX_ENABLE_ROLES. UGA在內(nèi)存中的位置依靠于會(huì)話的配置方式.假如會(huì)話連接的配置方式是專用服務(wù)器模式(DDS)即是一個(gè)會(huì)話對(duì)應(yīng)一個(gè)進(jìn)程,則UGA是放在PGA中的.在PGA中,Fixed UGA是其中的一個(gè)Chunk,而UGA HEAP是PGA的一個(gè)子堆(Subheap).假如會(huì)話連接是配置為共享服務(wù)器模式(MTS), Fixed UGA是SHARED POOL中的一個(gè)Chunk,而UGA HEAP則是SHARED POOL中的子堆(Subheap) The CGA: 跟其它的全局區(qū)不同,Call Global Area是短暫性存在的.它只有在調(diào)用數(shù)據(jù)期間存在,一般是在對(duì)實(shí)例的最低級(jí)別的調(diào)用時(shí)才需要CGA,如下: 分析一個(gè)SQL語(yǔ)句 執(zhí)行一個(gè)SQL語(yǔ)句
取出一個(gè)SELECT語(yǔ)句的輸出 一個(gè)單獨(dú)的CGA在遞歸調(diào)用時(shí)是需要的.在SQL語(yǔ)句的分析過(guò)程中,對(duì)數(shù)據(jù)字典信息的遞歸調(diào)用是需要的,因?yàn)橐獙?duì)SQL語(yǔ)句進(jìn)行語(yǔ)法分析,還有在語(yǔ)句的優(yōu)化期間要計(jì)算執(zhí)行計(jì)劃.執(zhí)行PL/SQL塊時(shí)在處理SQL語(yǔ)句的執(zhí)行時(shí)也是需要遞歸調(diào)用的,在DML語(yǔ)句的執(zhí)行時(shí)要處理觸發(fā)器執(zhí)行也是需要遞歸調(diào)用的. 不管UGA是放在PGA中還是在SGA中,CGA都是PGA的一個(gè)子堆(Subheap).這個(gè)事實(shí)的一個(gè)重要推論是在一個(gè)調(diào)用的期間會(huì)話必須是一個(gè)進(jìn)程.對(duì)于在一個(gè)MTS的Oracle數(shù)據(jù)庫(kù)進(jìn)程應(yīng)用開(kāi)發(fā)時(shí)關(guān)于這一點(diǎn)的理解是很重要的.假如相應(yīng)的調(diào)用較多,就得增加processes的數(shù)量以適應(yīng)調(diào)用的增加. 沒(méi)有CGA中的數(shù)據(jù)結(jié)構(gòu),CALLS是沒(méi)法工作的.而實(shí)際上跟一次CALL相關(guān)的數(shù)據(jù)結(jié)構(gòu)一般都是放在UGA中,如SQL AREA,PL/SQL AREA和SORT AREA它們都必須在UGA中,因?yàn)樗鼈円诟鰿ALLS之間要一直存在并且可用.而CGA中所包含的數(shù)據(jù)結(jié)構(gòu)是要在一次CALL結(jié)束后能夠釋放的.例如CGA包含了關(guān)于遞歸調(diào)用的信息,直接I/O BUFFER等還有其它的一些臨時(shí)性的數(shù)據(jù)結(jié)構(gòu). Java Call Memory也是在CGA中.這一段內(nèi)存比Oracle的其它內(nèi)存段治理得更密集.它分成三個(gè)Space: Stack Space, New Space, Old Space.在New Space和Old Space中不再被參考使用的Chunks,根據(jù)它們?cè)谑褂闷陂g的長(zhǎng)度及SIZE的不同,在調(diào)用的執(zhí)行過(guò)程中將被當(dāng)成不用的Chunks收集起來(lái).New Space Chunks很多次的不用的Chunks的反復(fù)收集過(guò)程中沒(méi)有被收集的Chunks將會(huì)被放到Old Space Chunks中.這是在Oracle內(nèi)存治理中唯一的一個(gè)廢物收集(garbage collection),其它的Oracle內(nèi)存段都是釋放Dead Chunks. Process Memory Allocation 跟SGA不一樣的是,SGA在實(shí)例啟動(dòng)之后SIZE就已經(jīng)是定下來(lái)的,而PGA的SIZE是會(huì)增長(zhǎng)的.通過(guò)使用malloc()或者sbrk()系統(tǒng)調(diào)用來(lái)為進(jìn)程增加堆數(shù)據(jù)段大小而使得PGA的SIZE的增長(zhǎng).OS的新虛擬內(nèi)存會(huì)被做為PGA HEAP中的一個(gè)新的區(qū)被加到PGA中來(lái).這些區(qū)一般只幾KB大,假如有需要,Oracle將會(huì)給分配上千個(gè)區(qū). 操作系統(tǒng)對(duì)每個(gè)進(jìn)程的堆數(shù)據(jù)段的增長(zhǎng)是有限制的.大部分的情況是操作系統(tǒng)的內(nèi)存參數(shù)進(jìn)行限制(kernel parameter: MAXDSIZ),有一些情況它的缺省值是可以以每個(gè)進(jìn)程為基準(zhǔn)進(jìn)行修改的.對(duì)于所有的進(jìn)程,操作系統(tǒng)對(duì)整個(gè)虛擬內(nèi)存也有一個(gè)系統(tǒng)全局性的限制,這個(gè)限制跟系統(tǒng)的SWAP SPACE相關(guān).一旦超過(guò)了這兩個(gè)限制,Oracle的進(jìn)程在執(zhí)行中會(huì)碰到ORA-4030錯(cuò)誤. ORA-4030這個(gè)錯(cuò)誤的產(chǎn)生一般不是因?yàn)槊總€(gè)進(jìn)程的資源限制而是因?yàn)镾WAP SPACE空間不足造成.為了診斷這個(gè)問(wèn)題可以使用操作系統(tǒng)的一些選項(xiàng)來(lái)查看SWAP SPACE的使用情況.另外,在一些操作系統(tǒng)中,Oracle包含了一個(gè)工具叫maxmem,它可以用來(lái)查看每個(gè)進(jìn)程可以被分配的堆數(shù)據(jù)段的最大SIZE以及哪一個(gè)限制是第一次超過(guò)的. 假如這個(gè)問(wèn)題的出現(xiàn)是因?yàn)镾WAP SPACE空間不足,而且換頁(yè)的動(dòng)作非常頻繁而且較多,則需要減少系統(tǒng)一級(jí)的虛擬內(nèi)存的使用,這個(gè)可以通過(guò)減少進(jìn)程數(shù)也可以通過(guò)減少每個(gè)進(jìn)程的內(nèi)存限制.假如換頁(yè)動(dòng)作不頻繁而且比較少,則需要調(diào)大SWAP SPACE SIZE. Process Memory Deallocation: Oracle堆的增長(zhǎng)比它們的收縮要來(lái)得輕易,當(dāng)然它們的SIZE也是可以收縮的.在V$MYSTAT和V$SESSTAT視圖中,session的統(tǒng)計(jì)信息session uga memory和session pga memory分別顯示了當(dāng)前session的UGA和PGA的內(nèi)存大小,包含內(nèi)部的空閑空間.相應(yīng)的統(tǒng)計(jì)信息session uga memory max 和 session pga memory max分別顯示了在session的生存期間所使用過(guò)得最大的UGA和最大的PGA. UGA和PGA只有在特定的操作后才會(huì)收縮,這些操作如一次磁盤排序的合并操作,或者用程序DBMS_SESSION.FREE_UNUSED_USER_MEMORY顯示釋放內(nèi)存.只有整個(gè)free heap extent會(huì)被釋放給父堆或者是進(jìn)程堆數(shù)據(jù)段,所以有一部分的內(nèi)部free space在內(nèi)存釋放后仍然存在于subheap中. 在大多的操作系統(tǒng)環(huán)境下,Oracle是不會(huì)減少進(jìn)程堆數(shù)據(jù)段也不會(huì)釋放虛擬內(nèi)存并將其返還給操作系統(tǒng)的.所以從一個(gè)操作系統(tǒng)的查看中,一個(gè)Oracle的進(jìn)程將會(huì)把虛擬內(nèi)存SIZE作為HWM而保留著.假如有必要時(shí),Oracle是會(huì)將一些沒(méi)用的虛擬內(nèi)存頁(yè)換頁(yè)出去的.因?yàn)檫@個(gè)原因,有關(guān)Oracle進(jìn)程的虛擬內(nèi)存頁(yè)的操作系統(tǒng)統(tǒng)計(jì)信息都是很難理解的.所以一般用的是Oracle內(nèi)部統(tǒng)計(jì)信息來(lái)代替使用操作系統(tǒng)的統(tǒng)計(jì)信息. 程序DBMS_SESSION.FREE_UNUSED_USER_MEMORY只能在連接是配置為MTS模式的應(yīng)用才能使用.這個(gè)最好是少點(diǎn)使用,因?yàn)樗会尫糯蟮陌腶rray變量所占用的內(nèi)存返還給Large Pool或者是Shared Pool.一般地,UGA HEAP的內(nèi)存應(yīng)該首先被釋放,可以通過(guò)指派新的空array給array變量使用,也可以通過(guò)調(diào)用程序DBMS_SESSION.RESET_PACKAGE.