V$MEMORY_DYNAMIC_COMPONENTS是确认ASMM是否启用的最可靠视图,若返回结果中shared pool、buffer cache等组件CURRENT_SIZE非零且动态变化,且SGA_TARGET>0、MEMORY_TARGET=0,则ASMM已生效;否则可能处于AMM或手动管理模式。
如何确认当前是否已启用ASMM
直接查 v$memory_dynamic_components 视图最可靠。如果返回结果中 component 列包含 shared pool、buffer cache、large pool 等,且它们的 current_size 都非零且随时间变化,说明 asmm 已生效。若所有组件大小固定不变,或只看到 sga_target 为 0,则 asmm 未启用。
常见误判点:仅看 SHOW PARAMETER sga_target 不够——它可能非零,但若 MEMORY_TARGET > 0,Oracle 实际走的是 AMM(自动内存管理),ASMM 被覆盖,SGA 组件不再独立动态调整。
-
SGA_TARGET> 0 且MEMORY_TARGET = 0→ ASMM 模式 -
MEMORY_TARGET> 0 → AMM 模式(ASMM 不起作用) - 两者均为 0 → 手动 SGA 管理
启用ASMM的关键参数设置
必须同时满足两个条件:设 SGA_TARGET 为非零值,并确保 MEMORY_TARGET = 0。否则 Oracle 会优先启用 AMM,ASMM 自动失效。
操作建议:
- 用
ALTER SYSTEM SET SGA_TARGET = 4G SCOPE=BOTH;启用 ASMM(数值按实际物理内存 40%~60% 预估) - 立即执行
ALTER SYSTEM SET MEMORY_TARGET = 0 SCOPE=BOTH;,防止残留配置干扰 - 若原用 SPFILE,重启前检查
SHOW PARAMETER memory_target确认已为 0;否则下次启动仍可能触发 AMM - 禁用
LOCK_SGA(除非有特殊需求),否则 ASMM 无法动态收缩/扩张组件
ASMM下各SGA组件还能手动调吗
可以,但有限制。ASMM 允许你为部分组件设“下限”,即最小保障值;超出下限的部分由 Oracle 动态调度。
典型可设下限的组件包括:
-
SHARED_POOL_SIZE:设太小会导致硬解析激增,建议不低于 512MB(OLTP)或 1G(混合负载) -
DB_CACHE_SIZE:设为 0 表示完全交由 ASMM 管理;设具体值则成为缓冲区缓存最低保障 -
LARGE_POOL_SIZE、JAVA_POOL_SIZE同理,设为 0 才真正“放开”给 ASMM -
LOG_BUFFER不能由 ASMM 调整,始终需手动指定(通常 64MB 足够)
注意:一旦为某组件设了非零下限,ASMM 就不能再把它缩到该值以下——这会挤占其他组件可用空间,可能导致共享池 OOM 或缓存命中率骤降。
为什么设置了SGA_TARGET却没看到组件自动变化
最常见原因是操作系统级限制没到位,尤其是 /dev/shm 大小不足。ASMM 依赖 POSIX 共享内存段,而 Oracle 19c 默认把 SGA 映射到 /dev/shm。如果这里只有默认的 4GB(很多系统是 2GB),而你的 SGA_TARGET 设了 6G,Oracle 会静默降级为手动管理模式,不报错也不警告。
验证与修复步骤:
- 运行
df -h /dev/shm,确认容量 ≥SGA_TARGET - 若不足,临时扩容:
mount -o remount,size=8G /dev/shm - 永久生效需修改
/etc/fstab中 tmpfs 行,例如:tmpfs /dev/shm tmpfs defaults,size=8G 0 0 - 重启数据库后,再查
V$MEMORY_DYNAMIC_COMPONENTS,应能看到组件大小开始浮动
另一个隐蔽原因:实例启动时 SGA_MAX_SIZE 小于 SGA_TARGET。Oracle 会强制截断,但不会提示。务必保证 SGA_MAX_SIZE ≥ SGA_TARGET,且最好设为略大(如 +512MB),留出 ASMM 调优余量。











