作者: fuyuncat
来源: www.HelloDBA.com
PGA 是一段包含一个Oracle 服务或后台进程的数据和控制信息的内存。PGA 的大小依赖与系统的配置。在专用服务(Dedicated Server )模式下,一个服务进程与一个用户进程相关,PGA 就包括了堆空间和UGA 。而UGA (User Global Area 用户全局区)由用户会话数据、游标状态和索引区组成。在共享服务(MTS )模式下,一个共享服务进程被多个用户进程共享,此时UGA 是Shared Pool 或Large Pool 的一部分(依赖与配置)。
许多DBA 都不理解PGA 和UGA 之间的区别。其实这种区别可以简单的理解为进程和会话直接的区别。在专用服务模式下,进程和会话是一对一的;而在MTS 模式下,进程和会话是一对多的关系。PGA 是服务于进程的,它包含的是进程的信息;而UGA 是服务于会话的,它包含的是会话的信息。因此,MTS 模式下,PGA 和UGA 之间的关系也是一对多的。
UGA 中包含了一个会话的信息,包括:
o 打开游标的永久区和运行区;
o 包的状态信息,特别是包的变量;
o Java 会话的信息;
o 激活的角色;
o 激活的跟踪事件(ALTER SESSION SET EVENT … );
o 起作用的NLS 参数(SELECT * FROM NLS_SESSION_PARAMETERS; );
o 所有打开的db link ;
o 会话对于信任的Oracle 的托管访问标记(mandatory access control (MAC )
和PGA 一样,UGA 也由两组区组成,固定UGA 和可变UGA (或者说UGA 堆)。固定UGA 包含了大概70 个原子变量、小的数据结构以及指向UGA 堆的指针。
UGA heap 中的段可以通过表X$KSMUP 查到(它的结构和X$KSMSP 相同)。UGA 堆包含了存储一些固定表(X$ 表)的永久内存(依赖与特定参数的设置,如OPEN_CURSORS ,OPEN_LINKS 和MAX_ENABLED_ROLES )。除此以外,大部分的UGA 用于私有SQL 区。UGA 内存的所在依赖于会话的设置。在专用服务模式下,会话和进程是一对一的关系,UGA 位于PGA 中。固定UGA 是PGA 中的一段内存段,而UGA 堆是PGA 的子堆。在MTS 模式下,固定UGA 是shared pool 中的一段内存段,而UGA 堆是Large Pool 的子堆,如果从large pool 分配失败,则从shared pool 中分配。
MTS 模式下,可以通过Profile 中的PRIVATE_SGA 项(通过dba_profiles 查看)来控制每个UGA 占用的SGA 的总的大小,但是不建议这样做。
Oracle 9.2 以后,有一个新的隐含参数:_use_realfree_heap 。当设置这个参数为true 时,Oracle 会为CGA 、UGA 单独分配堆,而不从PGA 中分配。它的默认值为false ,而当设置了pga_aggregate_target 后,它的值自动被改为true 。
与其他的全局区不同,CGA (Call Global Area 调用全局区)的存在是瞬间的。它只存在于一个调用过程中。对于实例的一些低层次的调用需要CGA ,包括:
o 解析一条SQL 语句;
o 执行一条SQL 语句;
o 取一条SELECT 语句的输出值。
如果语句产生了递归调用,则需要为每个递归调用分配一个CGA 。如上所述,递归调用是在语句解析、优化器产生语句查询计划、DML 操作时需要查询或修改数据字典信息的调用。
无论UGA 存在于PGA 还是SGA ,CGA 都是PGA 的subheap 。因为无论那种模式,会话在做调用时总需要一个进行进行处理。这一点很重要,特别是在MTS 模式下时,如果发现一次调用很久没有响应,则可能需要增加PGA 的大小。
当然,调用并不是只通过CGA 中的数据结构来工作。实际上,调用所需要的大部分的重要数据结构都来自于UGA 。例如私有SQL 取和排序区都存放在UGA 中,因为调用结束后,它们是被保留的。CGA 中只包含了那些调用结束后可以被释放的数据。例如,CGA 中包含了直接IO 缓存、关于递归调用的信息、用于表达式评估(产生查询计划时)的的堆空间和其他一些临时数据。
Java 调用内存也分配在CGA 中。它被分为三部分空间:堆空间、新空间和老空间。在调用期间(调用长短依赖于使用期长短和大小),在新空间和老空间中的内存段不再使用的内存段将被垃圾收集器回收。
软件代码区是一部分用于存放那些正在运行和可以被运行的代码(Oracle 自身的代码)的内存区。Oracle 代码一般存储在一个不同于用户程序存储区的软件代码区,而用户程序存储区是排他的、受保护的区域。
软件区的大小一般是固定的,只有Oracle 软件升级或重装后才会改变。在不同操作系统下,这部分区域所要求的大小也不同。
软件区是只读的,可以被安装成共享的或非共享的。可能的情况下,Oracle 代码是共享的,这样所有Oracle 用户都可以直接访问这些代码,而不需要各自保存一份拷贝在自己的内存中。这样可以节省大量内存并提高整体性能。
而用户程序也可以是共享的或非共享的。一些Oracle 工具(如SQL Plus )能被安装成共享的,但有些不能。如果一台机器运行多个实例,这些实例可以使用同一个Oracle 代码区。
另外要注意的是:并不是所有操作系统都能将软件区安装成共享的,如Windows 。