Language Environment(以下简称LE)是z/OS环境的一个组件,其为一些高级语言的IBM版本(例如C,C++, COBOL,Fortan及PL/I等)提供了一个公共的运行环境。Heap storage是LE用来进行存储管理(Storage Management)的一个概念。在heap storage中通常包含程序运行过程中动态分配的存储空间。本文主要介绍 heap storage的基本组成结构,并通过一个简单的例子来展示heap storage中的内容是如何随着申请和释放操 作而变化的,从而帮助用户更深入的理解heap storage。
首先我们介绍几个与heap有关的术语。
Heap:Heap是被LE程序所使用的一段存储区域。Heap通常包 含一个初始heap segment(片段)和0个或者多个增量(incremental)
Heap segment:LE从操作系统获得的连续的存储区域
Heap element:通过LE的API调用CEEGTST分配的一段连续的存储区域。Heap element总是在一个heap segment中分配的
Heap incremental:当初始heap segment无法满足对heap storage的申请请求时,LE额外从操作系统获得 的heap segments
(为了减少翻译带来的歧义,下文尽可能使用如element,segment这样的英文术语)
接下来我们介绍在31位模式下Heap storage的布局:
每一个heap segment的开始部分都是一个长度为32个字节(8个全字)的heap header。Heap header包含以 下8个字段,每个字段的长度都是4个字节:
1. 一个四个字符的Eyecatcher,内容为“HANC”,用来标示一个heap segment的开始
2. 指向下一个heap segment或者HPCB(Heap Control Block)的指针
3. 指向前一个heap segment或者HPCB的指针
4. heapid
5. 指向此segment起始地址的指针(即Segment address)
6. Segment中最大的空闲element的开始地址(也可称为根地址(root address))
7. Heap segment的长度(即Segment length)
8. Segment中最大的空闲element的长度(也可称为根元素长度(root element length))
在heap header之后,则包含了已经分配的或者是空闲的heap element。
对于一个已经分配的element,首先是8个字节的header,分成两个部分:前四个字节是这个element所在的 segment的开始地址;接下来的四个字节表示这个element的长度(包含8个字节的header在内的长度);后面 则全是用户数据区域。
一个segment中所有空闲的element,组成了一个Cartesian tree(笛卡尔树)。对于空闲的element,在开 始的部分,同样有16个字节的header,分成4个长度均为4字节的字段,分别表示左节点的地址,右节点的地址 ,左节点的大小和右节点的大小(对于笛卡尔树和左右节点的概念,我们不在本文中描述)。每个节点都表示 一个空闲的element。
获得一个segment的起始地址后,我们就可以通过Header中的root address ,以及每个free segment的 header,定位到这个segment之内所有空闲的elements。
图1是一个简单的示意图。这个图描述了一个Heap segment,其中包含了Heap Header,两个已经分配的和 两个空闲的element。图中的绿色箭头和红色箭头,分别表示指向segment开始地址的指针和指向空闲segment 开始地址的指针。
图1