oracle内存全面分析(7) 1.3. uga (the user global area) pga是一段包含一个oracle服务或后台进程的数据和控制信息的内存。pga的大小依赖与系统的配置。在专用服务(dedicated server)模式下,一个服务进程与一个用户进程相关,pga就包括了堆空间和uga。而u
oracle内存全面分析(7)
1.3. uga (the user global area)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。
注释:依赖与特定参数的设置,如open_cursors,open_links和max_enabled_roles,是什么意思?
说设置某个参数为true才会在固定表(x$表)的永久内存里创建该参数对应的视图吗或是设置某个参数为某值则在固定表(x$表)的永久内存里该参数对应的视图的数据量存储空间就会有变化?
1.4. cga (the call global area)与其他的全局区不同,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中。它被分为三部分空间:堆空间、新空间和老空间。在调用期间(调用长短依赖于使用期长短和大小),在新空间和老空间中的内存段不再使用的内存段将被垃圾收集器回收。
1.5. 软件代码区(software code area)软件代码区是一部分用于存放那些正在运行和可以被运行的代码(oracle自身的代码)的内存区。oracle代码一般存储在一个不同于用户程序存储区的软件代码区,而用户程序存储区是排他的、受保护的区域。
软件区的大小一般是固定的,只有oracle软件升级或重装后才会改变。在不同操作系统下,这部分区域所要求的大小也不同。
软件区是只读的,可以被安装成共享的或非共享的。可能的情况下,oracle代码是共享的,这样所有oracle用户都可以直接访问这些代码,而不需要各自保存一份拷贝在自己的内存中。这样可以节省大量内存并提高整体性能。
而用户程序也可以是共享的或非共享的。一些oracle工具(如sql plus)能被安装成共享的,但有些不能。如果一台机器运行多个实例,这些实例可以使用同一个oracle代码区。
另外要注意的是:并不是所有操作系统都能将软件区安装成共享的,如windows。