ASMM频繁调整组件大小属正常现象,因其本就通过MMAN进程定期评估负载并动态重分配shared pool、buffer cache等内存;只要单次变化≤1GB、无持续单向趋势且无ORA-04031或严重latch等待,即为健康行为。

AWR 显示 ASMM 频繁调整组件大小,不是异常,而是 ASMM 正常工作的表现——它本就该动,关键看“动得是否合理、有无副作用”。
ASMM 的动态调整机制本身就会写入 AWR
Oracle 10g 起引入的 ASMM 依赖后台进程 MMAN 定期(默认每 5 分钟)评估负载变化,并触发 SGA 内部组件(shared pool、db_cache_size、large_pool 等)的内存重分配。这些调整动作会被记录进 V$SGA_DYNAMIC_COMPONENTS,并在 AWR 报告的 “SGA Dynamic Components” 部分汇总呈现。
常见现象包括:
- AWR 中看到
Database Buffer Cache大小在 12GB ↔ 14GB 之间来回波动 -
Shared Pool在白天 OLTP 高峰时收缩、夜间 DSS 批处理时扩张 - 每次快照间隔内出现多次“resize”事件(查
DBA_HIST_SGA_DYNAMIC_COMPONENTS可确认)
只要调整幅度不大(单次变化 ≤ 1GB)、无持续单向增长/收缩趋势、且未伴随 ORA-04031 或严重 latch 等待,就属于健康行为。
频繁调整但伴随性能问题?重点查这三处
真正需要干预的“频繁调整”,是指它已引发资源争用或服务抖动。此时应跳过表象,直查根因:
-
statistics_level必须为typical或all:设为basic会禁用 ASMM 的顾问功能,导致 MMAN 盲调或失效 - 检查是否有硬解析泛滥:
Parse CPU to Parse Elapsd %> 80% 或Hard Parse %> 10%,说明大量 SQL 未绑定变量,Shared Pool 被反复冲刷,ASMM 被迫频繁扩容又收缩 - 确认未被 ASMM 管理的固定内存是否吃紧:
log_buffer、db_keep_cache_size等手动设置项过大,会挤压 ASMM 可调度空间,逼它在更小范围内高频震荡
如何验证 ASMM 调整是否“过频”或“失当”
别只盯 AWR 里的“大小变化”,要结合时间维度和系统响应看:
- 执行:
SELECT snap_id, component, current_size - LAG(current_size) OVER (PARTITION BY component ORDER BY snap_id) delta_mb FROM dba_hist_sga_dynamic_components WHERE snap_id IN (SELECT MAX(snap_id) FROM dba_hist_snapshot) - 10 AND snap_id >= (SELECT MAX(snap_id) FROM dba_hist_snapshot) - 20 ORDER BY component, snap_id;—— 查最近 10 次快照内各组件的单次变化量 - 若某组件(如
shared pool)连续 5 次快照中 delta_mb 绝对值均 > 512MB,且方向交替(+600 → -550 → +580),说明它正被反复拉扯,大概率是硬解析或游标泄漏所致 - 对比同一时段的
DB Time和Average Active Sessions:如果调整最频繁的时段恰好对应 AAS 波峰,且 Top Event 是latch: shared pool,那 ASMM 不是问题,而是症状
ASMM 的“动”是结果,不是原因。真正该静下来查的,永远是 SQL 写法、绑定变量使用、统计信息新鲜度,以及那些被你手动钉死却早已不匹配当前负载的内存参数。


















