【深入解析--eygle】 學習筆記
UGA(用戶全局區)由用戶會話數據、游標狀態和索引區組成。在共享服務器模式下,一個共享服務進程被多個用戶進程共享,此時UGA是Shared Pool或Large Pool的一部分,而在專用服務器模式下,UGA則是PGA的一部分。
不考慮Shared Server模式,在Dedicated模式下,PGA與UGA關系,就如同Process和Session的關系,PGA是服務於進程的內存結構,包含進程信息;而UGA是服務於會話的,它包含的是會話的信息。UGA中包含如下信息:
(1)打開游標的永久區和運行區;
(2)包的狀態信息以及變量信息;
(3)Java會話的狀態信息;
(4)啟用角色信息、跟蹤事件;
(5)起作用的NLS參數;
(6)所有打開的database links;
(7)會話訪問控制信息等
UGA也由兩組區組成,固定UGA和可變UGA(或者說UGA堆)。固定UGA包含了大概70個原子變量、小的數據結構以及指向UGA堆的指針。
UGA中的內存分配可以通過內部表X$KSMUP(X$KSMUP - [K]ernel [S]ervice[M]emory [U]GA Hea[P])查詢得到。UGA堆包含了存儲一些固定表(X$表)的永久內存(依賴於特定參數的設置,如OPEN_CURSORS,OPEN_LINKS和MAX_ENABLED_ROLES)。
sys@felix SQL>select ADDR,KSMCHCOM,KSMCHPTR,KSMCHSIZ,KSMCHCLS,KSMCHTYP,KSMCHPAR from x$ksmup;
ADDR KSMCHCOM KSMCHPTR KSMCHSIZ KSMCHCLS KSMCHTYP KSMCHPAR
------------------------------------------------ ---------------- ---------- -------------------------- --
00007F528F1D6920dbgdInitEventGr 00007F528F23FFB0 80freeabl 0 00
00007F528F1D68C8 sessionlanguag 00007F528F23FD60 592freeabl 0 00
00007F528F1D6870 SessionNCHAR l 00007F528F23FB10 592freeabl 0 00
00007F528F1D6818 kdlw:UGAstate 00007F528F23FAC8 72freeabl 0 00
00007F528F1D67C0 kdlu:UGAstate 00007F528F23FAA0 40 freeabl 0 00
00007F528F1D6768kzsrcrdi 00007F528F23F960 320freeabl 0 00
00007F528F1D6710kzctxhugi1 00007F528F23E948 4120 freeabl 0 00
00007F528F1D66B8 PLS ccahp desc 00007F528F23E7D0 376freeabl 0 00
00007F528F1D6660 PLS ccahp desc 00007F528F23E658 376freeabl 0 00
00007F528F1D6608 PLS UGAhp 00007F528F23DE50 2056recr 409500007F528F23E7E8
00007F528F1D65B0 kgsc htsegs 00007F528F23DE30 32freeabl 0 00
00007F528F1D6558 kgsc htsegs 00007F528F23DE10 32freeabl 0 00
00007F528F1D6500 kgsc htsegs 00007F528F23DDF0 32freeabl 0 00
00007F528F1D64A8 kgsc htsegs 00007F528F23DDD0 32 freeabl 0 00
00007F528F1D6450 kgsc htsegs 00007F528F23DDB0 32freeabl 0 00
00007F528F1D63F8 kgsc htsegs 00007F528F23DD90 32freeabl 0 00
00007F528F1D63A0 kgsc htsegs 00007F528F23DD70 32freeabl 0 00
00007F528F1D6348 kgsc htsegs 00007F528F23DD50 32freeabl 0 00
00007F528F1D62F0 kgsc htsegs 00007F528F23DD30 32freeabl 0 00
00007F528F1D6298 kgsc htsegs 00007F528F23DD10 32freeabl 0 00
00007F528F1D6240 kgsc htsegs 00007F528F23DCF0 32 freeabl 0 00
00007F528F1D61E8 kgsc htsegs 00007F528F23DCD0 32freeabl 0 00
00007F528F1D6190 kgsc htsegs 00007F528F23DCB0 32freeabl 0 00
00007F528F1D6138 kgsc htsegs 00007F528F23DC90 32freeabl 0 00
00007F528F1D60E0 kgsc htsegs 00007F528F23DC70 32freeabl 0 00
從Oracle9iR2開始,有一系列新的隱含參數被引入用於控制自動的PGA管理,這其中有一個關鍵的參數是_use_realfree_heap,當設置這個參數為true時,Oracle會為CGA、UGA單獨分配堆,而不從PGA中分配。它的默認值為false,而當設置了pga_aggregate_target後,它的值自動被改為true:
SQL>SELECT x.ksppinm NAME, y.ksppstvl VALUE,x.ksppdesc describ
FROMSYS.x$ksppi x, SYS.x$ksppcv y
WHEREx.indx = y.indx AND x.ksppinm LIKE '%&par%';
Enter value for par: realfree
old 3:WHERE x.indx = y.indx AND x.ksppinm LIKE '%&par%'
new 3:WHERE x.indx = y.indx AND x.ksppinm LIKE '%realfree%'
NAME VALUE DESCRIB
----------------------------------------------------- -----------------------------------------
_realfree_heap_max_size 32768 minimum max total heap size, in Kbytes
_realfree_heap_pagesize_hint 65536 hint for real-free page size in bytes
_realfree_heap_mode 0 mode flags for real-free heap
_use_realfree_heap TRUE use real-free based allocator for PGAmemory
SQL>
_use_realfree_heap 是自動管理PGA技術的關鍵技術變化,realfree代表著實時釋放。Oracle9i之前手工管理的PGA的主要問題在於,UGA缺省的在PGA中分配,當會話執行了諸如排序、HASH-JOIN等操作,耗用了大量PGA內存,而當會話執行完畢之後,內存會釋放給PGA而不是OS,在很多時候這會導致過度的PGA內存使用(在以前版本PGA內存分配和回收是通過malloc()以及brk()調用來完成的);從Oracle9iR2開始,自動的PGA內存管理當_use_realfree_heap為true時,PGA的內存分配將會通過mmap()調用來實現,這樣當調用結束時將不必將內存返回給進程而直接返回給OS,從而實現了更好的PGA內存分配與使用。
通過V$PGASTAT視圖可以查詢PGA累計釋放回OS的內存空間:
SQL> select name,value from v$pgastat wherename like '%OS';
NAME VALUE
---------------------------------------- -----------
PGA memory freed back to OS 175374336
下圖是UGA的結構示意圖:
在PGA的示意圖中,還涉及了另外一塊內存區域被稱為CGA(Call Global Area)-調用全局區。與其他的全局區不同,CGA的存在是瞬間的,只存在於調用過程中,而且無論UGA存在於PGA還是SGA,CGA都是PGA的SubHeap。對 於 實 例 的 一 些 低 層 次 的 調 用(Low-Level Call )需要CGA,包括分析SQL語句、執行SQL語句以及獲取查詢結果都需要使用CGA,在SQL執行過程中的每個遞歸調用需要一個獨立的CGA,在SQL的解析過程中,查詢數據字典信息、對SQL進行語法以及語義的解析、SQL的優化以及不同執行計劃的評估都需要使用CGA。
當然,調用並不是只通過CGA中的數據結構來工作,實際上調用所需要的大部分的重要數據結構都來自於UGA(如SQL AREA, PL/SQL AREA,Sort Area都存放在UGA中,因為這些結構在調用期間需要一直可用),CGA中只包含了那些調用結束後可以被釋放的數據。例如,CGA中包含了Direct I/O BUFFER、遞歸調用信息、表達式評估的堆棧信息等,此外Java調用內存也在CGA中分配。