oracle内存碎片

oracle内存碎片是由于频繁的申请,释放,拆分chunk,从而导致拆分成很多小的chunk,这就是内存碎片。碎片有什么危害呢,可能造成shared pool latch的冲突。
我们需要为大的内存需求保留空间,避免申请大chunk的时候,结果没有,申请不到。对于非常大的对象,oracle可以单独保留一个区域为此分配空间,shared_pool_reserved_size,这个值缺省应该是shared_pool_size 的5%,这块区域完全和正常的chunk不相往来,单独存在,v$shared_pool_reserved可以通过这个视图查看这块区域的使用情况。这个区域的管理是先进先出原则,怎么避免内存碎片呢,首先大的对象keep到内存,可以用dbms_shared_pool.keep,具体使用自己研究一下,这里无论是存储对象还是临时的,都可以keep。减少大的匿名块,比如PL/SQL,还有就是避免共享池太大,共享池够用就好,如果共享池很大,小的chunk申请又多,那么就造成很多碎片,freelist就会很长,持有的shared_pool_latch就会时间长,CPU遍历的时候就会很耗资源,所以加大共享池不是解决此种冲突的方法,这个时候最关键的还是看一下为什么不能共享SQL语句。从9I开始,oracle开始引入了多个共享池的概念,所以大的共享池不会再那么差劲,可以最多有7个子latch保护共享池,要配置多个共享池,首先硬件要足够的硬,呵呵。CPU够多,内存够大。比如一个hash桶油18000个chunk,如果只有一个共享池,那么只能遍历这18000个,如果配置了6个子共享池,那么平均一个hash桶就是18000/6,一个shared_pool_latch也就是原来的1/6时间就可以完成。子共享池的个数可以通过隐含参数_kghdsidx_count手动调节,同事也指定了几个child latch,可以通过select a.ksppinm,b.ksppstvl from x$ksppi a,x$ksppsv b where a.indx=b.indx and a.ksppinm=’_kghdsidx_count’;查看你的数据库有几个共享池。看了一下,10G默认的子共享池个数是2个,相对的,增加了共享池,你就可以适当的增加共享池的大小,每个子共享池有自己的LRU列表,和shared_pool_latch.v$db_object_cache存放了钉住的对象信息,或者可以设置cursor_sharing=force.这个设置比较复杂,这里是强制绑定变量,具体以后分解。

你活着,证明了什么?