Oracle的記憶體的分配、回收[final]
Oracle中的共享記憶體區的分配都是以chunk為最小單位的。Chunk不是一個固定值,它是一個擴充套件段(extent)中一塊連續的記憶體。而Oracle的記憶體(其他儲存,如磁碟也是)的增長是以擴充套件段為基礎的。
1. 空閒列表和LRU連結串列
空閒的chunk按照大小來組織在相應的空閒列表(Free List)中。而未pin住的、可重建(unpinned recreatable)的chuck被維護在兩個分別用於週期性chunk和短期chunk的LRU連結串列中。子堆還有一個包含少許空閒記憶體的主永久記憶體chunk。
2. 空閒記憶體分配和回收
空閒記憶體都是由空閒列表(free list)統一管理、分配的。每個空閒的chunk(大塊)都會屬於也只屬於一個空閒列表。空閒列表上的chunk的大小範圍是由bucket來劃分的。Bucket直譯為“桶”,在西方,往往用桶來盛裝一定品質範圍的物品,以便查詢。比如,在採礦時,用不同的桶來裝不同純度的礦石,在桶上標明礦石的純度範圍,以便在提煉時可以採用不同工藝。在這裡,我們也可以把bucket視為一種索引,使Oracle在查詢空閒塊時,先定位所需的空閒塊在哪個bucket的範圍內,然後在相應的空閒列表中查詢。
一次記憶體的分配過程如下:當一個程式需要一個記憶體的大塊(chunk)時,它會先掃描目標空閒列表(每個空閒列表對應有一個bucket,bucket是這個空閒列表的中chunk的大小範圍)以查詢最適合大小的chunk。如果找不到一個大小正好合適的chunk,則繼續掃描空閒列表中更大的chunk。如果找到的可用chunk比所需的大小大24位元組或者更多,則這個chunk就會被分裂,剩餘的空閒chunk又被加到空閒列表的合適位置。如果空閒列表中沒有一個chunk能滿足要求的大小,則會從非空的相鄰bucket的空閒列表中取最小的chunk。如果所有空閒列表都是空的,就需要掃描LRU連結串列釋放最近最少使用的記憶體。當chunk空閒時,如果相鄰的chunk也是空閒的,它們可能會結合(coalesce)起來。
當所有空閒列表都沒有合適的空閒chunk可用時,就開始掃描LRU連結串列,將最近最少使用的chunk釋放掉(如有空閒的相鄰chunk,則結合),放到相應的空閒列表種去,直到找到合適的chunk或者達到最大查詢數限制。如果在釋放了LRU連結串列中最近最少使用的chunk後沒沒有找到合適空閒chunk,系統就拋4031錯誤。
如果找到了可用空閒chunk,就將它從空閒列表中移出,放到LRU連結串列中去。
下面介紹一下Shared Pool的分配和回收。
3. Shared Pool的分配和回收
在Shared Pool中,空閒列表掃描、管理和chunk分配的操作都是受到shared pool latch保護的。顯然,如果shared pool含有大量的非常小的空閒chunk,則掃描空閒列表時間將很長,而shared pool latch則會要保持很久。這就是導致shared pool latch爭用的主要原因了。有些DBA透過增加shared pool來減少shared pool latch爭用,這種方法是沒有用的,可能反倒會加劇爭用(作為短期解決方法,可以flush shared pool;而要真正解決問題,可以採取在例項啟動時keep住那些可能會斷斷續續使用的物件【這種物件最容易導致shared pool碎片】)。
只有執行了ALTER SYSTEM FLUSH SHARED_POOL才會使shared pool的空閒chunk全結合起來。因此,即使shared pool空閒記憶體之和足夠大,也可能出現記憶體請求失敗(空閒記憶體都是一些很小的碎片chunk)。
實際上,oracle例項啟動時,會保留大概一半的Shared Pool,當有記憶體壓力時逐漸釋放它們。Oracle透過這種方法限制碎片的產生。Oracle的少量空襲記憶體(spare free memory)和X$表即其他持久記憶體結構一起,隱含在shared pool的主要持久記憶體chunk中。這些記憶體不在shared pool的空閒列表中,因此能夠立即被分配。但是,卻包含在檢視V$SGASTAT的free memory的統計資料中。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-676656/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JVM垃圾回收器、記憶體分配與回收策略JVM記憶體
- JVM 之 記憶體分配與回收策略JVM記憶體
- JVM垃圾回收和記憶體分配策略JVM記憶體
- Oracle的記憶體分配和使用Oracle記憶體
- 窺探JVM記憶體分配和回收的過程JVM記憶體
- 視覺化分析js的記憶體分配與回收視覺化JS記憶體
- jvm:記憶體模型、記憶體分配及GC垃圾回收機制JVM記憶體模型GC
- 垃圾回收與記憶體分配——總結篇記憶體
- 淺談JVM記憶體分配與垃圾回收JVM記憶體
- V8 記憶體分配與垃圾回收記憶體
- oracle9i 的記憶體分配Oracle記憶體
- JVM記憶體分配策略,及垃圾回收演算法JVM記憶體演算法
- Java虛擬機器記憶體分配與回收策略Java虛擬機記憶體
- 【SGA】【PGA】普適的Oracle記憶體分配策略Oracle記憶體
- Oracle記憶體分配與調整Oracle記憶體
- Oracle記憶體分配與使用(zt)Oracle記憶體
- 記憶體分配的確定記憶體
- weblogic的記憶體分配Web記憶體
- Android記憶體分配/回收的一個問題-為什麼記憶體使用很少的時候也GCAndroid記憶體GC
- 記憶體的分配與釋放,記憶體洩漏記憶體
- Oracle記憶體分配經驗法則Oracle記憶體
- C語言的記憶體分配C語言記憶體
- 物件的建立與記憶體分配物件記憶體
- go是如何分配記憶體的?Go記憶體
- 控制C++的記憶體分配C++記憶體
- 記憶體分配的隱藏成本記憶體
- C中的記憶體分配模型記憶體模型
- JavaScript記憶體分配JavaScript記憶體
- JVM記憶體分配JVM記憶體
- java記憶體分配Java記憶體
- 簡單理解動態記憶體分配和靜態記憶體分配的區別記憶體
- Java的記憶體回收機制Java記憶體
- 垃圾收集器與記憶體分配策略_記憶體分配策略記憶體
- linux記憶體管理(一)實體記憶體的組織和記憶體分配Linux記憶體
- oracle 記憶體分配和調優 總結Oracle記憶體
- _ksmg_granule_size oracle記憶體分配粒度Oracle記憶體
- Go記憶體分配和GC的理解Go記憶體GC
- JVM 記憶體模型 記憶體分配,JVM鎖JVM記憶體模型