Process Memory的详细信息 (二)


The CGA:

跟其它的全局区不同 ,Call Global Area 是短暂性存在的 . 它只有在调用数据期间存在 , 一般是在对实例的最低级别的调用时才需要 CGA, 如下 :

分析一个 SQL 语句

执行一个 SQL 语句

取出一个 SELECT 语句的输出

一个单独的 CGA 在递归调用时是需要的 . 在 SQL 语句的分析过程中 , 对数据字典信息的递归调用是需要的 , 因为要对 SQL 语句进行语法分析 , 还有在语句的优化期间要计算执行计划 . 执行 PL/SQL 块时在处理 SQL 语句的执行时也是需要递归调用的 , 在 DML 语句的执行时要处理触发器执行也是需要递归调用的 .

不管 UGA 是放在 PGA 中还是在 SGA 中 ,CGA 都是 PGA 的一个子堆 (Subheap). 这个事实的一个重要推论是在一个调用的期间会话必须是一个进程 . 对于在一个 MTS 的 Oracle 数据库进程应用开发时关于这一点的理解是很重要的 . 如果相应的调用较多 , 就得增加 processes 的数量以适应调用的增加 .

没有 CGA 中的数据结构 ,CALLS 是没法工作的 . 而实际上跟一次 CALL 相关的数据结构一般都是放在 UGA 中 , 如 SQL AREA,PL/SQL AREA 和 SORT AREA 它们都必须在 UGA 中 , 因为它们要在各 CALLS 之间要一直存在并且可用 . 而 CGA 中所包含的数据结构是要在一次 CALL 结束后能够释放的 . 例如 CGA 包含了关于递归调用的信息 , 直接 I/O BUFFER 等还有其它的一些临时性的数据结构 .

Java Call Memory 也是在 CGA 中 . 这一段内存比 Oracle 的其它内存段管理得更密集 . 它分成三个 Space: Stack Space, New Space, Old Space. 在 New Space 和 Old Space 中不再被参考使用的 Chunks, 根据它们在使用期间的长度及 SIZE 的不同 , 在调用的执行过程中将被当成不用的 Chunks 收集起来 .New Space Chunks 很多次的不用的 Chunks 的反复收集过程中没有被收集的 Chunks 将会被放到 Old Space Chunks 中 . 这是在 Oracle 内存管理中唯一的一个废物收集 (garbage collection), 其它的 Oracle 内存段都是释放 Dead Chunks.

Process Memory Allocation

跟 SGA 不一样的是 ,SGA 在实例启动之后 SIZE 就已经是定下来的 , 而 PGA 的 SIZE 是会增长的 . 通过使用 malloc() 或者 sbrk() 系统调用来为进程增加堆数据段大小而使得 PGA 的 SIZE 的增长 .OS 的新虚拟内存会被做为 PGA HEAP 中的一个新的区被加到 PGA 中来 . 这些区一般只几 KB 大 , 如果有需要 ,Oracle 将会给分配上千个区 .

操作系统对每个进程的堆数据段的增长是有限制的 . 大部分的情况是操作系统的内存参数进行限制 (kernel parameter: MAXDSIZ), 有一些情况它的缺省值是可以以每个进程为基准进行修改的 . 对于所有的进程 , 操作系统对整个虚拟内存也有一个系统全局性的限制 , 这个限制跟系统的 SWAP SPACE 相关 . 一旦超过了这两个限制 ,Oracle 的进程在执行中会遇到 ORA-4030 错误 .

ORA-4030 这个错误的产生一般不是因为每个进程的资源限制而是因为 SWAP SPACE 空间不足造成 . 为了诊断这个问题可以使用操作系统的一些选项来查看 SWAP SPACE 的使用情况 . 另外 , 在一些操作系统中 ,Oracle 包含了一个工具叫 maxmem, 它可以用来查看每个进程可以被分配的堆数据段的最大 SIZE 以及哪一个限制是第一次超过的 .

如果这个问题的出现是因为 SWAP SPACE 空间不足 , 而且换页的动作非常频繁而且较多 , 则需要减少系统一级的虚拟内存的使用 , 这个可以通过减少进程数也可以通过减少每个进程的内存限制 . 如果换页动作不频繁而且比较少 , 则需要调大 SWAP SPACE SIZE.

Process Memory Deallocation:

Oracle 堆的增长比它们的收缩要来得容易 , 当然它们的 SIZE 也是可以收缩的 . 在 V$MYSTAT 和 V$SESSTAT 视图中 ,session 的统计信息 session uga memory 和 session pga memory 分别显示了当前 session 的 UGA 和 PGA 的内存大小 , 包含内部的空闲空间 . 相应的统计信息 session uga memory max 和 session pga memory max 分别显示了在 session 的生存期间所使用过得最大的 UGA 和最大的 PGA.

UGA 和 PGA 只有在特定的操作后才会收缩 , 这些操作如一次磁盘排序的合并操作 , 或者用程序 DBMS_SESSION.FREE_UNUSED_USER_MEMORY 显示释放内存 . 只有整个 free heap extent 会被释放给父堆或者是进程堆数据段 , 所以有一部分的内部 free space 在内存释放后仍然存在于 subheap 中 .

在大多的操作系统环境下 ,Oracle 是不会减少进程堆数据段也不会释放虚拟内存并将其返还给操作系统的 . 所以从一个操作系统的查看中 , 一个 Oracle 的进程将会把虚拟内存 SIZE 作为 HWM 而保留着 . 如果有必要时 ,Oracle 是会将一些没用的虚拟内存页换页出去的 . 因为这个原因 , 有关 Oracle 进程的虚拟内存页的操作系统统计信息都是很难理解的 . 所以一般用的是 Oracle 内部统计信息来代替使用操作系统的统计信息 .

程序 DBMS_SESSION.FREE_UNUSED_USER_MEMORY 只能在连接是配置为 MTS 模式的应用才能使用 . 这个最好是少点使用 , 因为它只释放大的包的 array 变量所占用的内存返还给 Large Pool 或者是 Shared Pool. 一般地 ,UGA HEAP 的内存应该首先被释放 , 可以通过指派新的空 array 给 array 变量使用 , 也可以通过调用程序 DBMS_SESSION.RESET_PACKAGE.

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus