内存管理】Oracle AMM自动内存管理详解
一、 Oracle 的三种内存管理方式
oracle 内存管理有三种方式,每一个 instance 只能够选择一种。这三种管理方式分别是 AMM 自动内存管理( Automatic Memory Management )、 ASSM 自动共享内存管理( Auto Shared Memory Management )、 msmm 手动共享内存管理( Manual Shared Memory Management )。
本文针对AMM 自动内存管理进行详细原理阐述。
二、 AMM 原理阐述
自动内存管理automatic memory management (以下均称 AMM )是 oracle 11g 新推出的新特性,意在对实例中的 PGA 和 SGA 进行自动管理。 AMM 是自动共享内存管理 automatic shared memory management ( ASMM )的拓展。
1. 在AMM 中涉及到的参数
- memory_max_target
- memory_target
- sga_max_size
- sga_target
- pga_aggregate_target
2. AMM 的启用
方式一 :DBCA 图形界面下,要选择 AMM 自动内存管理, step9 选择 use Automatic Memory Management 即可。如下图
方式二 :可以通过以下两个参数之一启用
- memory_target :定义 sga 和 pga 总和的上限
- memory_max_taregt :定义 memory_target 的上限
假设memory_max_target 设置为 1400m , memory_target 设置为 1000m ,那么只有 1000m 会被用在 instance 中,剩下的 400m 会被 oracle 用做储备。因为 memory_max_target 已经指定了,所以可以动态的修改 memory_target 参数,而不需要重启数据库。
如果memory_max_target 和 memory_target 相同,或者 memory_max_target 没有设置,那么 memory_target 就不能动态增长,并且修改后需要重启 instance 。
memory_max_target 将一直在参数文件中显式设置,或者被内存管理后台进程隐式设置。 memory_max_target 会定义 instance 锁定的内存。如果 memory_max_target 没有在参数文件中设置,那么他的大小默认为 mrmory_target 。
3. AMM 的选项参数
所有的SGA 内存参数都会设置在 AMM 环境,如果 SGA 参数没有被设置,那么内存管理器将会进行以下设置:
60% to sga_target
40% to pga_aggregate_target
其他选项参数如下:
- sga_max_size :这个参数设置 memory_target 中 SGA 的上限
- sga_target :这个参数设置 memory_target 中的下限
- pga_aggregate_target :这个参数仅是 instance 允许所有进程使用内存的总量。在 AMM 中,这个参数将随着 memory_target 的空闲空间进行浮动。
SGA 和 PGA 的总量不能超过 memory_target 。如果 sga_target 在参数文件中设置,它将代表着 SGA 的下限。此时 pga_aggregate_target 将会获得的内存 = ( memory_target - sga_target )
4. 通过memory_target 控制内存
DBA 可以通过一些选项去决定如何对内存中的各个组件进行分配。可以通过 MEMORY_TARGET 来控制 PGA 和 SGA 的增长。由于 memory_target 同时管理者 PGA 和 SGA ,内存控制器可以自由的在两者之间进行内存控制,没有任何的限制。如果要限制 PGA 的增长,可以设置 sga_target 参数大小,这就限制了 SGA 的最小值。在这种情况下, PGA 就算增长,也不能让 SGA 缩小到超过他的最小值。如果要限制 SGA 的增长,可以设置 sga_max_size 的大小,这是 SGA 的上限值。
如果想要设置SGA 中某个组件的最小值,也可以进行单独设置。 SGA 中重要的组件如下:
- shared pool (通过 shared_pool_size 参数管理)
- buffer cache (通过 db_cache_size 参数管理)
- streams pool (通过 streams_pool_size 参数管理)
- java pool (通过 java_pool_size 参数管理)
- large pool (通过 large_pool_size 参数管理)
三、 实验测试
情况一
只设置memory_target
- memory_target =1G
memory_max_target 不设置,所以它会被默认设置大小为 memory_target 。
执行以下SQL :
SQL> show parameter memory;
NAME TYPE VALUE
-------------------- -- -- ----------- ----------------------
hi_shared_memory_address integer 0
memory_max_target big integer 1G
memory_target big integer 1G
shared_memory_address integer 0
SQL> select * from v$sgainfo where name like 'Maximum SGA%' or name like 'Free SGA%';
NAME BYTES RES
-------------------------------- ---------- ---
Maximum SGA Size 1068937216 No
Free SGA Memory Available 432013312
SQL> select component,current_size from v$memory_dynamic_components where component like '%Target%';
COMPONENT CURRENT_SIZE
------------------------------------------------ ------------
SGA Target 641728512
PGA Target 432013312
总结 :
1) 初始所有的内存(1G )会作为共享内存分配, v$sgainfo 显示 SGA 最大值为 1G ,因为 sga_max_size 没有设置,因此默认 sga 最大值为 memory_target 。
2) v$sgainfo 显示,有 412M 是空闲的内存,这些空闲的内存可以用在 PGA ,或者动态的设置 SGA 。
3) 内存的初始比是60% 给 SGA,40% 给 PGA 。在 sga_target 和 pga_aggregate_target 没有设置的情况下,这是默认的情况。这也就意味着,内存的 60% ( 612M )给 SGA ,内存的 40% ( 412M )给 PGA 。
4) v$memory_dynamic_components 显示sga_target 设置 612M , pga_aggregate_target 设置 412M 。这里的 pga_aggregate_target 设置为 412M 不意味着 PGA 已经达到了 412M 。而是说明有 412M 空间可以给 PGA 增长。如果它增长超过 412M ,那么内存控制器将会从 SGA 中获取内存。
情况二
设置以下参数
- memory_target=1G
- sga_target=300M
- pga_aggregate_target=100M
memory_max_target 不设置,所以它默认值等于 memory_target 。
执行以下SQL :
SQL> select * from v$sgainfo where name like 'Maximum SGA%' or name like 'Free SGA%';
NAME BYTES RES
-------------------------------- ---------- ---
Maximum SGA Size 1068937216 No
Free SGA Memory Available 759169024
SQL> select component,current_size from v$memory_dynamic_components where component like '%Target%';
COMPONENT CURRENT_SIZE
------------------------------------------------- ------------
SGA Target 314572800
PGA Target 759169024
总结:
1) 初始所有内存(1G )会被作为共享内存分配。 v$sgainfo 显示, SGA 最大值为 1G ,因为 SGA_MAX_SIZE 没有设置,所以它默认大小等于 memory_target 。
2) v$sgainfo 显示 724M 为空闲内存,这个值是由 memory_target 减去 sga_target 得到的。这些空闲内存可以用于 PGA 和 SGA ,并由 oracle 自动控制。
3) v$memory_dynamic_components 视图显示SGA 设置为 300M, 但是 PGA 设置为 724M ,这个大小是 memory_target 分配后的剩余部分。这里的 PGA 的值为 724M ,并不意味着 PGA 已经占有了 724M ,也是意味着 PGA 可以占有最大值为 724M 。
4) sga_target_size 默认值为 1G ,理论上这个就是 SGA 的最大值。
情况三
设置以下参数
- memory_target=1G
- sga_max_size=500m
- sga_target=300m
- pga_aggregate_target=100m
由于memory_max_target 没有设置,所以它默认大小为 memory_target 。
SQL> select * from v$sgainfo where name like 'Maximum SGA%' or name like 'Free SGA%';
NAME BYTES RES
-------------------------------- ---------- ---
Maximum SGA Size 521936896 No
Free SGA Memory Available 209715200
SQL> select component,current_size from v$memory_dynamic_components where component like '%Target%';
COMPONENT CURRENT_SIZE
---------------------------------------- ------------
SGA Target 314572800
PGA Target 759169024
总结:
1) 现在sga_target_size 设置为 500M , v$sgainfo 显示 SGA 最大值为 500M
2) v$sgainfo 中显示, SGA 可用值介于 sga_target 和 sga_max_size 之间
3) 超过sga_max_size ( 500M )的内存不会给 SGA 使用,所以不会显示在 v$sgainfo 中
4) v$memory_dynamic_components 视图中显示SGA 设置为 300M , PGA 设置为 700M 。这个 700M 的值,是 memory_target 减去 sga_target 得到的。
---- end ----