shared pool之二:free lists/shared pool lru list

介绍free lists及shared pool lru list.

Shared pool中chunk的分配

1、shared pool中的chunk的大小是不一样的,但是是连续的   
2、因为chunk是分配的最小单元,因此session需要给对象分配空间的时候,会以chunk为单位进行申请    
3、可用的chunk(free)会形成一个链表 feee lists,便于进行分配的时候,可以通过遍历链表寻找到可用的适合的chunk,链表是chunk进行组织和管理的一种方式
4、一个可用的chunk链表是一个bucket,shared pool中会有很多的bucket,不同的bucket中的chunk的大小不同,一般是随着bucket编号的增加而增长的
5.当需要从shared pool中寻找chunk的时候,首先会定位一个bucket,然后遍历bucket,寻找最合适的chunk, 如果chunk的空间比需要的空间大,那么这个chunk就拆分成两个,一个被分配、一个成为free,重新挂接到相应大小的bucket上。   
6、在寻找chunk的过程中,如果一个bucket中没有合适的chunk,接着寻找另外一个非空的bucket,如果所有的bucket中都没有合适的chunk,那么就从rec类型的链表中释放一部分的空间,为free,或将free做适当合并  。。注意:只有rec类型的chunk能够被释放空间,即使释放了空间,这些空间可能都不是连续的,都是一些很小的chunk,这样可能形成这样一种情况,shared pool中有空间但是是大量的非常小的chunk,这样在寻找chunk的时候,也很难寻找到合适的chunk--共享池碎片
7、shared pool中所有类型的chunk都是以链表的方式进行管理的
##############

free list 空闲列表

按bucket划分,共有255个,bucket 0---bucket 254   
每个bucket上挂有一个 chunk list; free lists上的都是未使用的chunk--状态free
free lists上Bucket大小的分布情况:  --环境LINUX 32位/ORACLE 11.2.0.4
Bucket 0-199之前 Bucket size以4bytes递增
Bucket 200-239这一段的Bucket size以64bytes递增
Bucket 240--254的Bucket size增长看起来没太大规律,总之是递增了哈哈。
因为free chunk数量非常的多,这样划分每个Bucket容纳的chunk数量减少,查找效率提高,对shared pool latch的争用也大大减少。注意:如果在shared pool中出现了大量的小的free chunk,就会出现share pool latch争用的情况,即使增加共享池的大小,这个问题随着时间还是会出现的。
RESERVED FREE LISTS:
RESERVED FREE LISTS上的bucket个数我DUMP出来的是15个。
保留FREE LISTS,在SQL语句所需CHUNK大于4400bytes时,会在RESERVED FREE LISTS中查找空闲CHUNK。
如果SQL语句所需CHUNK不大于4400bytes时,只会在free list 中查找CHUNK。
这个是由隐含参数控制的:_shared_pool_reserved_min_alloc          minimum allocation size in bytes for reserved area ,默认值4400   
###################
DUMP 共享池查看free lists/bucket/RESERVED FREE LISTS结构:--用新建会话来做
alter session set events 'immediate trace name heapdump level 2';
select value from v$diag_info where name like 'De%';
/u01/diag/rdbms/bys3/bys3/trace/bys3_ora_7876.trc
查看TRACE文件内容: --找这一段的方法:VI搜索HEAP DUMP
  Chunk 2bffa844 sz=    22460    freeable  "character set m"
Total heap size    =146798680    -- 146798680/1024/1024 --139.99813    初始化参数:shared_pool_size--140M
FREE LISTS:        ------空闲列,可以明显看出bucket大小分配的规律--从小到大,共有255个buckets,从16bytes到64k,采用此方法分配内存,可以有效的减少内存碎片。每个Bucket之间都用double linked 相互连接
 Bucket 0 size= 16
  Chunk 2bc00048 sz=        0    kghdsx
 Bucket 1 size=20   20字节的Bucket 1,有很多个Chunk,节约篇幅省略了
  Chunk 23a60468 sz=       20    free      "               "
  Chunk的地址、大小、状态
  Chunk 23ceb498 sz=       20    free      "               "
  Chunk 237fcde4 sz=       20    free      "               "
 Bucket 2 size=24   --Bucket 2   --24字节,也就是Bucket 2的 size范围在20-24字节。。
  Chunk 245b13e4 sz=       24    free      "               "
  Chunk 23ace7c0 sz=       24    free      "               "
  Chunk 239c5a28 sz=       24    free      "               "
 Bucket 3 size=28
  Chunk 24540e9c sz=       28    free      "               "
  Chunk 2521209c sz=       28    free      "               "
  Chunk 23483448 sz=       28    free      "               "
………………
 Bucket 198 size=1388
 Bucket 199 size=1452
                   ---------- Bucket 200之前 Bucket size以4bytes递增
  Chunk 2347d2ac sz=     1492    free      "               "
 Bucket 200 size=1516                                                  ----------Bucket 200之后 Bucket size以64bytes递增
  Chunk 24b28a94 sz=     1548    free      "               "
 Bucket 201 size=1580                                              
  Chunk 2433bb14 sz=     1620    free      "               "
  Chunk 2463a89c sz=     1620    free      "               "
  Chunk 24b829c4 sz=     1620    free      "               "
 Bucket 202 size=1644
  Chunk 23498518 sz=     1704    free      "               "
  Chunk 23de90d0 sz=     1696    free      "               "
………………
 Bucket 236 size=3820
 Bucket 237 size=3884
 Bucket 238 size=3948
 Bucket 239 size=4012               --------------Bucket 200到-Bucket 239这一段的Bucket size以64bytes递增
 Bucket 240 size=4096               -----------Bucket 239之后 的Bucket size增长看起来没太大规律,总之是递增了哈哈
 Bucket 241 size=4100
 Bucket 242 size=4108
 Bucket 243 size=8204
 Bucket 244 size=8460
 Bucket 245 size=8464
 Bucket 246 size=8468
 Bucket 247 size=8472
 Bucket 248 size=9296
 Bucket 249 size=9300
 Bucket 250 size=12320
 Bucket 251 size=12324
 Bucket 252 size=16396
 Bucket 253 size=32780
 Bucket 254 size=65548
Total free space   =   518232
RESERVED FREE LISTS:   --保留FREE LISTS,解析方法同上。保留池中CHUNK都比较大
 Reserved bucket 0 size=16
  Chunk 23420320 sz=      676  R-free      "               "
  Chunk 23427b94 sz=     3420  R-free      "               "
  Chunk 2342618c sz=      952  R-free      "               "
  Chunk 23800050 sz=     1040  R-free      "               "
  Chunk 23400050 sz=     2824  R-free      "               "
  Chunk 25bff028 sz=     4032  R-free      "               "
  Chunk 293ff788 sz=     2144  R-free      "               "
 Reserved bucket 1 size=4400  --这个如果用的会,4564-4400,剩下164字节会成为新CHUNK
  Chunk 23430a40 sz=     4564  R-free      "               "
 Reserved bucket 2 size=8204
 Reserved bucket 3 size=8460
 Reserved bucket 4 size=8464
 Reserved bucket 5 size=8468
 Reserved bucket 6 size=8472
  Chunk 2342b988 sz=     9136  R-free      "               "
 Reserved bucket 7 size=9296
 Reserved bucket 8 size=9300
 Reserved bucket 9 size=12320
 Reserved bucket 10 size=12324
 Reserved bucket 11 size=16396
  Chunk 234161f8 sz=    16448  R-free      "               "
 Reserved bucket 12 size=32780
 Reserved bucket 13 size=65548
  Chunk 23401d50 sz=    72296  R-free      "               "
  Chunk 23815668 sz=   125312  R-free      "               "
  Chunk 23c00050 sz=   180380  R-free      "               "
 Reserved bucket 14 size=1990652
Total reserved free space   =  6712468   --总空闲保留空间是6.4M,shared_pool_reserved_size 初始化参数大小是 7M,用了0.6M
######################


shared pool LRU链

shared pool LRU链上挂的都是recreate、freeabl状态的chunk,一个SQL语句可能需要多个CHUNK,在LRU链上找到recreate状态的chunk,然后在 recreate状态的chunk下再下挂freeabl状态的CHUNK,--避免全部CHUNK在LRU链上导致LRU链太长。
TRACE文件中找到关于(lru first)的一段,方法同上:
 Reserved bucket 14 size=1990652
Total reserved free space   =  6712468
UNPINNED RECREATABLE CHUNKS (lru first):
  Chunk 246c9848 sz=      348    recreate  "KGLHD          "  latch=(nil)    -- latch状态为空, Chunk SIZE是348字节,状态 recreate
  Chunk 237cb10c sz=     4096    recreate  "KGLH0^b9197c6e "  latch=(nil)
  Chunk 24bb5df0 sz=      364    recreate  "KGLHD          "  latch=(nil)
  Chunk 241aa1b8 sz=     4096    recreate  "KGLH0^59449e50 "  latch=(nil)
  Chunk 252640a0 sz=      364    recreate  "KGLHD          "  latch=(nil)
  Chunk 23a619a0 sz=     4096    recreate  "KGLH0^d5f1e0d7 "  latch=(nil)
   Chunk 23465600 sz=      348    recreate  "KGLHD          "  latch=(nil)
  Chunk 2346575c sz=     1036    recreate  "KGLHD          "  latch=(nil)
  Chunk 23465b68 sz=     4096    recreate  "KGLH0^c6e0d102 "  latch=(nil)    --一个recreate状态CHUNK下的多个freeable状态CHUNK
     ds 24bdecb0 sz=     4096 ct=        1
  Chunk 23466b68 sz=     4096    freeable  "SQLA^1536bb77  "  ds=0x23db5bd8
  Chunk 23467b68 sz=      144    freeable  "KGLDA          "
  Chunk 23467bf8 sz=     4096    freeable  "KGLH0^ba3f9b05 "  ds=0x2425e238

猜你喜欢

转载自blog.csdn.net/qq_22083251/article/details/79673367