Oracle内存结构(三)----Process Memory的详细信息

The Process Memory:

除了 SGA(System Global Area) 之外 ,Oracle 进程还使用下面三个全局区 :

The Process Global Area (PGA)

The User Global Area (UGA)

The Call Global Area (CGA)

很多人都搞不清楚 PGA 和 UGA 两者之间的区别 , 实际上两者之间的区别跟一个进程和一个会话之间的区别是类似的 . 尽管说进程和会话之间一般都是一对一的关系 , 但实际上比这个更复杂 . 一个很明显的情况是 MTS 配置 , 会话往往会比进程多得多 . 在这种配置下 , 每一个进程会有一个 PGA, 每一个会话会有一个 UGA.PGA 所包含的信息跟会话是无任何关联的 , 而 UGA 包含的信息是以特定的会话为基础的 .

The PGA:

进程全局区 (PGA) 即可以理解为 Process Global Area, 也可以理解为 Program Global Area. 它的内存段是在进程私有区 (Process Private Memory) 而不是在共享区 (Shared Memory). 它是个全局区意味着它包含了所有代码有可能进入的全局变量和数据结构 , 但是它是不被所有进程共享的 . 每个 Oracle 的服务器进程都包含有属于自己的 PGA, 它只包含了本进程的相关特定信息 .PGA 中的结构不需要由 latches 来保护 , 因为其它的进程是不能进入到这里面来访问的 .

PGA 包含的是有关进程正在使用的操作系统资源信息以及进程的状态信息 , 而其它的进程所使用的 Oracle 的共享资源是在 SGA 中 .PGA 是私有的而不是共享的 , 这个机制是有必要的 , 因为当进程死掉后可以把这些资源清除和释放掉 .

PGA 包含两个主要区域 :Fixed PGA 和 Variable PGA 或称为 PGA Heap. Fixed PGA 的作用跟 Fixed SGA 是类似的 , 都包含原子变量 ( 不可分的 ), 小的数据结构和指向 Variable PGA 的指针 .

Variable PGA 是一个堆 . 它的 Chunks 可以从 Fixed Table X$KSMPP 查看得到 , 这个表的结构跟前面有提到的 X$KSMSP 是相同的 .PGA HEAP 包含了一些有关 Fixed Table 的永久性内存 , 它跟某些参数的设置有依赖关系 . 这些参数包含 DB_FILES,LOG_FILES,CONTROL_FILES.

The UGA:

UGA(User Global Area) 包含的是特定会话的信息 , 有如下一些 :

所打开游标的持续和运行时间内的区域

包的状态信息 , 特定的变量

Java 会话状态

可以用的 ROLES

被 ENABLE 的跟踪事件

起作用的 NLS 参数设置

打开的 DBLINK

会话的入口控制

跟 PGA 一样 ,UGA 也由两区组成 :Fixed UGA 和 Variable UGA, 也称为 UGA HEAP. Fixed UGA 包含了大约 70 个原子变量 , 小的数据结构和指向 Variable UGA 的指针 .

UGA HEAP 中的 Chunks 可以从它们自己的会话中通过查看表 X$KSMUP 获得相关信息 , 这个表的结构跟 X$KSMSP 是一样的 .UGA HEAP 包含了一些有关 fixed tables 的永久性内存段 , 跟一些参数的设置有依赖关系 . 这些参数有 OPEN_CURSORS,OPEN_LINKS, 和 MAX_ENABLE_ROLES.

UGA 在内存中的位置依赖于会话的配置方式 . 如果会话连接的配置方式是专用服务器模式 (DDS) 即是一个会话对应一个进程 , 则 UGA 是放在 PGA 中的 . 在 PGA 中 ,Fixed UGA 是其中的一个 Chunk, 而 UGA HEAP 是 PGA 的一个子堆 (Subheap). 如果会话连接是配置为共享服务器模式 (MTS), Fixed UGA 是 SHARED POOL 中的一个 Chunk, 而 UGA HEAP 则是 SHARED POOL 中的子堆 (Subheap)

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 <SPAN style="FONT-FAMILY: 宋体; mso-ascii-font

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