大程序支持
本主题提供了关于使用大型和超大型地址空间的型号来容纳需要超过缺省地址空间型号所提供容量的程序的信息。
大地址空间模型适用于AIX® 4.3及更高版本。 非常大的地址空间模型在 AIX 5.1 和更高版本上可用。
32 位进程的虚拟地址空间被划分为 16 个 256 兆字节的区域(或段),每个均由独立的硬件寄存器寻址。 操作系统将段 2 (虚拟地址 0x20000000-0x2FFFFFFF) 称为 process-private 段。 缺省情况下,此段包含用户堆栈和数据,包括堆。 进程专有段也包含进程的 u-block,它由操作系统使用,且不可被应用程序读取。
因为用户数据和堆栈共同使用单一段,所以它们的总计大小要稍小于 256 MB。 但是,某些程序需要大数据区 (已初始化或未初始化) ,或者它们需要使用 malloc 或 sbrk 子例程分配大量内存。 可以将程序构建为使用大或超大地址空间模型,以允许它们使用最多 2 GB 的数据。
通过提供一个非零的 maxdata 值,可以使现有的程序使用大或超大地址空间模型。 maxdata 值既可以从 LDR_CNTRL 环境变量,也可以从可执行文件中的字段获得。 一些程序具有缺省地址空间模型的相关性,因此如果使用大地址空间模型运行它们,它们将会中断。
了解大地址空间模型
大地址空间模型允许指定的程序使用多于 256 MB 的数据。 其他程序继续使用缺省的地址空间模型。 要允许程序使用大地址空间模型,请指定非零的 maxdata 值。 可以通过在构建程序时使用 ld 命令或通过在执行程序之前导出 LDR_CNTRL 环境变量来指定非零 maxdata 值。
当执行了使用大地址空间模型的程序时,系统保留所需的 256 MB 的段数量以容纳由 maxdata 值指定的数据量。 然后,由段 3 开始,将程序的初始数据从可执行文件读取到内存中。 在段 3 中开始数据读取,即使 maxdata 值小于 256 MB。 使用大地址空间模型,程序可以分别具有最多 8 段或 2 GB 或 3.25 GB 的数据。
在缺省地址空间模型中,有 12 个段可供 shmat 或 mmap 子例程使用。 当使用了大地址空间模型,为数据保留的段数减少了用于 shmat 和 mmap 子例程的段数。 因为数据大小最大值为 2 GB,所以至少 2 段一直可用于 shmat 和 mmap 子例程。
当使用了大地址空间模型时,用户堆栈保留在段 2 中。 因此,堆栈的大小限制为稍小于 256 MB。 但是,程序可以将其用户堆栈重新部署到共享内存段或已分配内存中。
虽然程序中已初始的数据大小可以是大的,但对文本大小仍有限制。 在程序的可执行文件中,文本部分的大小加上装入程序部分的大小必须小于 256 MB。 这是必需的,如此这些段才会适合单一的只读段(段 1,TEXT 段)。 可以使用 dump 命令来检查节大小。
了解超大地址空间模型
超大地址空间模型以与大地址空间模型几乎相同的方法启用大数据程序,但它们之间仍有几点不同。 要允许程序使用超大地址空间模型,您必须指定 maxdata 值和动态段分配 (dsa) 属性。 使用 ld 命令或 LDR_CNTRL 环境变量来指定 maxdata 值和 DSA 选项。
如果指定了 maxdata 值,那么超大地址空间模型遵循大地址空间模型,在该模型中,从段 3 开始程序数据被读取到内存中,且这些数据根据占据了尽可能多的段。 但执行期间,剩余的数据段并不被保留为数据区域,而是被动态地获得。 在程序的数据区需要段之前,它可以由 shmat 或 mmap 子例程使用。 使用超大地址空间模型,程序可以具有最多 13 段或 3.25 GB 的数据。 在这 13 段中,12 段或 3 GB 可用于 shmat 和 mmap 子例程。
当进程试图将其数据区域扩展到新段时,只要 shmat 或 mmap 子例程未正在使用该段,操作就可以成功执行。 程序可以调用 shmdt 或 munmap 子例程来停止使用段,以便该段可以用于数据区。 然而,段已经被用于数据区域后,它就不再用于其他任何用途,即使数据区域的大小已降低。
如果未和 dsa 属性一起指定 maxdata 值 (Maxdata = 0),那么会使上述行为产生微小的变动。 进程将和常规进程一样,在段 2 中保留其数据和堆栈。 进程将不具有对全局共享库的访问权,因此进程使用的所有共享库将被专有地装入。 按此种方式运行地优点在于,进程具有的 13 个段 (3.25 GB) 将全部可由 shmat 和 mmap 子例程使用。
为了降低 shmat 或 mmap 子例程使用可能用于数据区域的段的可能性,操作系统使用不同的规则,用于选择要返回的地址(如果未请求指定的地址)。 通常, shmat 或 mmap 子例程返回最低的可用段中的地址。 当使用了超大地址空间模型时,这些子例程将返回最高的可用段中的地址。 只要地址不是位于已经用于数据区域的段中,指定地址的请求就会成功。 指定 dsa 属性的所有进程均遵循此行为。
使用超大地址空间模型,可以指定 maxdata 值为零,或指定最大为 0xD0000000 的值。 如果指定的 maxdata 值大于 0xAFFFFFFF,那么程序将不会使用全局装入的共享库。 相反地,所有地共享库将被专有地装入。 这可能会影响程序性能。
启用大地址空间模型和超大地址空间模型
如果指定了 maxdata 值,而未指定动态段分配 (dsa) 属性,那么使用大地址空间模型。 如果给定了所有的 maxdata 值并指定了 dsa 属性,那么使用超大地址空间模型。 使用带有 -bmaxdata 标志的 ld 命令来指定 maxdata 值并设置 dsa 属性。
cc -bmaxdata:0x80000000 sample.o cc -bmaxdata:0xD0000000/dsa sample.o cc -bmaxdata:0xD0000000/dsa sample.o LDR_CNTRL=MAXDATA=0x80000000 a.outLDR_CNTRL=MAXDATA=0x80000000@DSA a.out0x80000000,请使用以下命令:/usr/ccs/bin/ldedit -bmaxdata:0x80000000 a.out/usr/ccs/bin/ldedit -bmaxdata:0x80000000/dsa a.out您可以使用 dump 命令来检查 maxdata 值,或者确定程序是否具有 dsa 属性。
一些程序具有缺省地址空间模型的相关性。 如果通过修改程序的可执行文件或设置 LDR_CNTRL 环境变量而指定非零的 maxdata 值,那么这些程序终止。
执行使用大数据区的程序
当您执行使用大地址空间模型的程序时,操作系统尝试修改数据大小软限制,如果需要,会将其增大以匹配 maxdata 值。 如果 maxdata 值大于当前数据大小的硬限制,那么在环境变量 XPG_SUS_ENV 的值设为 ON 时程序不会程序,或者软限制将设为当前的硬限制。
如果 maxdata 值小于程序静态数据的大小,那么程序不会执行。
在将程序的已初始或未初始数据放置在段 3 及其以后段中之后,计算中断值。 中断值定义进程静态数据的结束以及进程的动态可分配数据的开始。 通过使用 malloc, brk 或 sbrk 子例程,进程可以移动中断值以增加数据区的大小。
例如,如果程序指定的 maxdata 值为 0x68000000,那么最大中断值位于段 9 (0x98000000) 中间。 brk 子例程跨段边界扩展中断值,但数据区的大小不能超过当前软数据限制。
setrlimit 子例程允许进程将其软数据限制设置为不超过硬数据限制的任何值。 然而,数据区域的最大大小被限制为原来的 maxdata 值,向上舍入为 256 MB 的倍数。
多数的子例程不受大数据程序的影响。 shmat 和 mmap 子例程受影响最大,因为它们具有较少的可用段。 如果大数据地址模型程序发生派生,那么子进程继承当前的数据资源限制。
特殊注意事项
使用大数据空间的程序需要大量的调页空间。 例如,如果使用 2 GB 地址空间的程序试图访问其地址空间中的每个页面,那么系统必须具有 2 GB 的调页空间。 当调页空间运行低时,操作系统终止进程。 使用大数据空间的程序被首先终止,因为它们通常会消耗大量的调页空间。
调试使用大数据模型的程序与调试其他程序相同。 dbx 命令可以主动或从核心转储调试这些大型程序。 大数据程序的完全核心转储可能相当大。 要避免截断的核心文件,请确保 coredump 资源限制足够大,并确保文件系统中具有足够的可用空间以运行您的程序。
某些应用程序可能依赖缺省地址空间模型的特征而进行编写。 如果这些程序使用大或超大地址空间模型执行,它们可能不会正常运行。 当您运行这些程序时,不要设置 LDR_CNTRL 环境变量。
使用超大地址空间模型的进程必须对它们的程序进行代码更改,以便移动大于 2 GB 程序块中地址空间的中断值。 这是采用有符号的值作为参数的 sbrk 系统调用的一个限制。 其变通方法是,程序可以多次调用 sbrk 以将中断值移动到需要的位置。