Oracle記憶體結構:ProcessMemory的詳細資訊

tolywang發表於2007-09-27
The Process Memory:
  除了SGA(System Global Area)之外,Oracle程式還使用下面三個全域性區:
  The Process Global Area (PGA)
  The User Global Area (UGA)
  The Call Global Area (CGA)
  很多人都搞不清楚PGA和UGA兩者之間的區別,實際上兩者之間的區別跟一個程式和一個會話之間的區別是類似的.儘管說程式和會話之間一般都是一對一的關係,但實際上比這個更復雜.一個很明顯的情況是MTS配置,會話往往會比程式多得多.在這種配置下,每一個程式會有一個PGA,每一個會話會有一個UGA.PGA所包含的資訊跟會話是無任何關聯的,而UGA包含的資訊是以特定的會話為基礎的.


The PGA:
  程式全域性區(PGA)即可以理解為Process Global Area,也可以理解為Program Global Area.它的記憶體段是在程式私有區(Process Private Memory)而不是在共享區(Shared Memory).它是個全域性區意味著它包含了所有程式碼有可能進入的全域性變數和資料結構,但是它是不被所有程式共享的.每個Oracle的伺服器程式都包含有屬於自己的PGA,它只包含了本程式的相關特定資訊.PGA中的結構不需要由latches來保護,因為其它的程式是不能進入到這裡面來訪問的.
  PGA包含的是有關程式正在使用的作業系統資源資訊以及程式的狀態資訊,而其它的程式所使用的Oracle的共享資源是在SGA中.PGA是私有的而不是共享的,這個機制是有必要的,因為當程式死掉後可以把這些資源清除和釋放掉.
  PGA包含兩個主要區域:Fixed PGA和Variable PGA或稱為PGA Heap. Fixed PGA的作用跟Fixed SGA是類似的,都包含原子變數(不可分的),小的資料結構和指向Variable PGA的指標.
  Variable PGA是一個堆.它的Chunks可以從Fixed Table X$KSMPP檢視得到,這個表的結構跟前面有提到的X$KSMSP是相同的.PGA HEAP包含了一些有關Fixed Table的永久性記憶體,它跟某些引數的設定有依賴關係.這些引數包含DB_FILES,LOG_FILES,CONTROL_FILES.
The UGA:
  UGA(User Global Area)包含的是特定會話的資訊,有如下一些:
所開啟遊標的持續和執行時間內的區域
包的狀態資訊,特定的變數
Java會話狀態
可以用的ROLES
被ENABLE的跟蹤事件
起作用的NLS引數設定
開啟的DBLINK
會話的入口控制
  跟PGA一樣,UGA也由兩區組成:Fixed UGA和Variable UGA,也稱為UGA HEAP. Fixed UGA包含了大約70個原子變數,小的資料結構和指向Variable UGA的指標.
  UGA HEAP中的Chunks可以從它們自己的會話中透過檢視錶X$KSMUP獲得相關資訊,這個表的結構跟X$KSMSP是一樣的.UGA HEAP包含了一些有關fixed tables的永久性記憶體段,跟一些引數的設定有依賴關係.這些引數有OPEN_CURSORS,OPEN_LINKS,和MAX_ENABLE_ROLES.
  UGA在記憶體中的位置依賴於會話的配置方式.如果會話連線的配置方式是專用伺服器模式(DDS)即是一個會話對應一個程式,則UGA是放在PGA中的.在PGA中,Fixed UGA是其中的一個Chunk,而UGA HEAP是PGA的一個子堆(Subheap).如果會話連線是配置為共享伺服器模式(MTS), Fixed UGA是SHARED POOL中的一個Chunk,而UGA HEAP則是SHARED POOL中的子堆(Subheap)
The CGA:
  跟其它的全域性區不同,Call Global Area是短暫性存在的.它只有在呼叫資料期間存在,一般是在對例項的最低階別的呼叫時才需要CGA,如下:
分析一個SQL語句
執行一個SQL語句
取出一個SELECT語句的輸出
  一個單獨的CGA在遞迴呼叫時是需要的.在SQL語句的分析過程中,對資料字典資訊的遞迴呼叫是需要的,因為要對SQL語句進行語法分析,還有在語句的最佳化期間要計算執行計劃.執行PL/SQL塊時在處理SQL語句的執行時也是需要遞迴呼叫的,在DML語句的執行時要處理觸發器執行也是需要遞迴呼叫的.
  不管UGA是放在PGA中還是在SGA中,CGA都是PGA的一個子堆(Subheap).這個事實的一個重要推論是在一個呼叫的期間會話必須是一個程式.對於在一個MTS的Oracle資料庫程式應用開發時關於這一點的理解是很重要的.如果相應的呼叫較多,就得增加processes的數量以適應呼叫的增加.
  沒有CGA中的資料結構,CALLS是沒法工作的.而實際上跟一次CALL相關的資料結構一般都是放在UGA中,如SQL AREA,PL/SQL AREA和SORT AREA它們都必須在UGA中,因為它們要在各CALLS之間要一直存在並且可用.而CGA中所包含的資料結構是要在一次CALL結束後能夠釋放的.例如CGA包含了關於遞迴呼叫的資訊,直接I/O BUFFER等還有其它的一些臨時性的資料結構.
  Java Call Memory也是在CGA中.這一段記憶體比Oracle的其它記憶體段管理得更密集.它分成三個Space: Stack Space, New Space, Old Space.在New Space和Old Space中不再被參考使用的Chunks,根據它們在使用期間的長度及SIZE的不同,在呼叫的執行過程中將被當成不用的Chunks收集起來.New Space Chunks很多次的不用的Chunks的反覆收集過程中沒有被收集的Chunks將會被放到Old Space Chunks中.這是在Oracle記憶體管理中唯一的一個廢物收集(garbage collection),其它的Oracle記憶體段都是釋放Dead Chunks.
Process Memory Allocation
  跟SGA不一樣的是,SGA在例項啟動之後SIZE就已經是定下來的,而PGA的SIZE是會增長的.透過使用malloc()或者sbrk()系統呼叫來為程式增加堆資料段大小而使得PGA的SIZE的增長.OS的新虛擬記憶體會被做為PGA HEAP中的一個新的區被加到PGA中來.這些區一般只幾KB大,如果有需要,Oracle將會給分配上千個區.
  作業系統對每個程式的堆資料段的增長是有限制的.大部分的情況是作業系統的記憶體引數進行限制(kernel parameter: MAXDSIZ),有一些情況它的預設值是可以以每個程式為基準進行修改的.對於所有的程式,作業系統對整個虛擬記憶體也有一個系統全域性性的限制,這個限制跟系統的SWAP SPACE相關.一旦超過了這兩個限制,Oracle的程式在執行中會遇到ORA-4030錯誤.
  ORA-4030這個錯誤的產生一般不是因為每個程式的資源限制而是因為SWAP SPACE空間不足造成.為了診斷這個問題可以使用作業系統的一些選項來檢視SWAP SPACE的使用情況.另外,在一些作業系統中,Oracle包含了一個工具叫maxmem,它可以用來檢視每個程式可以被分配的堆資料段的最大SIZE以及哪一個限制是第一次超過的.
  如果這個問題的出現是因為SWAP SPACE空間不足,而且換頁的動作非常頻繁而且較多,則需要減少系統一級的虛擬記憶體的使用,這個可以透過減少程式數也可以透過減少每個程式的記憶體限制.如果換頁動作不頻繁而且比較少,則需要調大SWAP SPACE SIZE.
Process Memory Deallocation:
  Oracle堆的增長比它們的收縮要來得容易,當然它們的SIZE也是可以收縮的.在V$MYSTAT和V$SESSTAT檢視中,session的統計資訊session uga memory和session pga memory分別顯示了當前session的UGA和PGA的記憶體大小,包含內部的空閒空間.相應的統計資訊session uga memory max 和 session pga memory max分別顯示了在session的生存期間所使用過得最大的UGA和最大的PGA.
  UGA和PGA只有在特定的操作後才會收縮,這些操作如一次磁碟排序的合併操作,或者用程式DBMS_SESSION.FREE_UNUSED_USER_MEMORY顯示釋放記憶體.只有整個free heap extent會被釋放給父堆或者是程式堆資料段,所以有一部分的內部free space在記憶體釋放後仍然存在於subheap中.
  在大多的作業系統環境下,Oracle是不會減少程式堆資料段也不會釋放虛擬記憶體並將其返還給作業系統的.所以從一個作業系統的檢視中,一個Oracle的程式將會把虛擬記憶體SIZE作為HWM而保留著.如果有必要時,Oracle是會將一些沒用的虛擬記憶體頁換頁出去的.因為這個原因,有關Oracle程式的虛擬記憶體頁的作業系統統計資訊都是很難理解的.所以一般用的是Oracle內部統計資訊來代替使用作業系統的統計資訊.
  程式DBMS_SESSION.FREE_UNUSED_USER_MEMORY只能在連線是配置為MTS模式的應用才能使用.這個最好是少點使用,因為它只釋放大的包的array變數所佔用的記憶體返還給Large Pool或者是Shared Pool.一般地,UGA HEAP的記憶體應該首先被釋放,可以透過指派新的空array給array變數使用,也可以透過呼叫程式DBMS_SESSION.RESET_PACKAGE.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-84916/,如需轉載,請註明出處,否則將追究法律責任。

相關文章