关于共享段与SGA的一点理解 上一周买了两本书,google了不少文档资料,看了看部分linux源代码终于有了以下一些理解。 一 各类地址概念 1 逻辑地址:我们一般在用汇编语言写程序时可能用到 seg register :offset 2 线形地址:0x00000000~0xffffffff,用来描述进程的地址空间 3 x86上逻辑地址到线形地址的转换规则:线形地址=[seg register]+offset 4 现代操作系统进程的线形地址到物理地址的转换一般是通过分页机制来完成的 [注]: seg register 表示段寄存器里的值,[seg register]表示段寄存器里的值指向的段描述符(seg descriptor)的baseAddress值 二 OS进程段的概念 1 段是OS进程为管理进程运行时的空间组织而产生的一个东东。 2 x86 CPU在硬件上支持(且强制使用)分段;power等大多数RISC系列的CPU在硬件上都不支持。 3 x86 硬件分段实际使用情况: 我们熟知的x86上的操作系统(包括windows,linux)都有限的使用了硬件分段,一般都是用的OS软件分段。 方法:是将segment descriptor里的baseAddress和endAddress设置为0x00000000和0xffffffff 原因和目的: a 对高级语言各类特征或标准提供更好的支持以提高性能,比如如C语言里的指针(见三) b 利用segment descriptor提供硬件上的内核保护 c 使得虚拟空间管理起来简单高效统一 分段的原因: 一个程序文件要在进程里运行,那么的必须有指令,存储数据的空间,stack信息等等,这些东西是如何组织起来并正确运行的呢?OS扮演了这个组织者的角色,通过分段技术。 比如在LINUX命令行:sqlplus "/as sysdba" 此时shell会为我们创建一个进程来运行可执行文件sqlplus。首先读取sqlplus文件并根据sqlplus文件里的"相关信息"在进程空间的相关位置(线形地址)创建建段如TEXT,DATA,BSS,STACK等等,这里提到的"相关信息"是在程序编译链接时产生并记录在可执行文件里的 一般UNIX提供了不同的编译链接参数其中部分就是用来影响这些"相关信息"的 LINUX里就是用一些vm_area_struct结构来记录并管理这些段的。 这种软件分段出了起组织程序运行的功能外,还有个优点是不必为总个进程空间分配 pagetable项注意pagetable项与physical page的关系,有时进程有了pagetable项但系统还没为此项分配physical page 如果此时访问则会产生page faults 触发OS进行相应的处理,如果访问不存在的pagetable项(极特殊情况除外)则会产生segment fault 系统异常程序exit。 共享段是在进程运行过程中通过系统调用生成的并能被其他进程共享(LINUX里就是为进程增加一个vm_area_struct结构) 补充1: PowerPC-32 有些文档上将其32位地址说成[seg-4位][disp-28位],最大段为256M。这容易使读者产生误解。其实这里的32位就是线形地址不是我们常说的seg:disp逻辑地址。之所以IBM文档上这样讲是因为powerpc将线形地址转为物理地址时与intel处理方式并不一样,转换的中间有个virtual address的概念 IBM《PowerPC Operating Environment Architecture Book III Version 2.02》讲的比较详细 三 使用逻辑地址还是线形地址(需特别注意-本文重点)? 现代通用操作系统windows,linux,aix等在运行时都是使用线形地址而不是逻辑地址来访问数据,即使在硬件一级上强制用逻辑地址,但是OS都会通过将这个逻辑地址的OFFSET=线形地址的手段处理掉这个逻辑地址问题。不使用逻辑地址的原因有很多,读者可以考虑考虑。 下面是个证实不使用逻辑地址访问数据的方法: 想一想如果程序运行时用的是逻辑地址那么高级语言C里的“指针”如何实现呢?第一种:使用seg:disp来存指针变量 但是指针在32/64平台里都是32/64位的--可以建立一个指针数组然后计 算它的大小就知道了,所以排除了用seg:disp来存指针变量第二种:由一,所以存线形地址,但访问时先将线形地址转为逻辑地址然后访问 这种代价太大了,且多次一举。所以不可能进行这个转换 目前一些OS教材上经常提到的“逻辑地址”有点误导读者。其实即使我们用汇编语言写程序时用到了逻辑地址的概念,但是OS的汇编语言编译器在编译汇编语言程序时会对汇编语言程序进行处理,从而使得程序运行时全都通过线形地址来访问数据。简而言之,忘记逻辑地址这个概念。 由此得出结论: 1 oracle sga 里存储的那些addr值(其实就是指针)是线形地址 2 共享sga的后台进程,以及server porcess都会将sga绑定在进程里的相同线形地址上 如果不这样,那么这些进程不可能通过addr来访问在sga里的对象 3 ibm文档上说的"段"最大为256M只会影响进程分配多少pagetable项,并不会影响OS段的大小 4 shmmax的最大值只受OS管理段时的数据结构的一些限制 5 由于使用线形地址,sga分为多个共享段只会影响空间的使用,对性能几乎没有影响[@more@]
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10748419/viewspace-986915/
,如需转载,请注明出处,否则将追究法律责任。