Oracle的各种内存组织都是以HEAP形式的,每个HEAP包含一个HEAP句柄和一系列的内存EXTENT,每个EXTENT包含了一系列的连续的CHUNK。当一个HEAP创建的时候,首先通过kghini调用来初始化HEAP句柄。一个HEAP句柄包括一组FREE LIST BUCKETS和相应的SIZE参数。调用kghini()的重要参数包括:heap的extent大小、heap的freelist桶的数量、分配大小、分配类型等。FREE LIST上链接了相同分配类型的的CHUNK。当正在使用的CHUNK释放的时候,会被放入到大小小于等于该CHUNK的FREE LIST上去,在同一个FREE LIST里,CHUNK不按照大小排序。比如:
可以看出,其中Bucket 0是存放所有小余76字节的CHUNK,Bucket 10存放所有大于32780字节的CHUNK。其他Bucket存放的CHUNK都是大于其SIZE大小,小于下一个Bucket的SIZE大小的CHUNK。另外一点我们要注意的是,Bucket中的CHUNK不是按照大小排序的。上面的例子是8.1.5的,不同的版本下,Bucket的数量会有所不同。
从共享池分配空间通过调用kghalo()来实现,这个调用返回指向CHUNK空间的指针。分配的空间的大小通过REQ_SIZE参数传递,但是堆管理会根据判断分配被称为ACTUAL_SIZE的空间,ACTUAL_SIZE可能比REQ_SIZE大或者小,不过并不是无规律的。从共享池分配空间的基本顺序如下:
首先搜索FREE