在某些早期的编程语言中,内存部分为两个区域:一个区域包含着原子的表示,用作元素;另一个区域包含着有序的指针对。一对指针中,左边的指针被存储在一个名为car域中,右边的指针被存储在cdr域中,如下图所示:

从上图你可以看出,每一个原子都是一个具有类type域和value域的节点。type域包含着一个标签,它规定了值域中值的类型。该系统称为标记式类型的系统。当我们在程序执行的过程中对一个标记式值进行运算的时候,我们需要阅读标签来决定进行什么样的运算。这类机制称为“运行时解释型计算”,因为它和语言解释器在程序执行过程中所做的事很相似。
在上图中的有序只针对域内没有使用到只针对可以被连接到一起形成一个单独的单向链表,方法是使用它们的cdr域中的连接。这个有未使用的只针对组成的表称为可用空间表。
下面我们来讨论一下垃圾收集进程的工作原理。首先,我们假设每个表节点中都有一个特定的特殊位,称为标记位。这个标记位可以被设成一个或者两个值,free或者reserved。这个进程分为三个阶段完成。
第一阶段:
第一阶段称为初始化阶段,程序会遍历内存区,把每一个表节点设为free。
第二阶段:
第二阶段称为标记阶段,所有当前正在使用的列表节点被标记出来,其标记为设为reserved。
第三个阶段:
第三个阶段称为收集阶段,对列表空间进行一次清扫,所有标记为free的节点都被连接在一起组成一个新的可用空间列表。这个可用空间表现在包含着所有无法访问的节点,这些节点之前都没有导入到使用的结构内。这些无法访问的节点又是称为垃圾,而对它们进行标识并把它们连接在一起形成一个新的可用空间列表,这个过程称为垃圾收集。
下面,我们继续讨论动态内存分配的工作原理。
为了支持不同大小的java对象的动态内存的分配,我们不能使用在上面讨论的可用空间列表技术,这是应为可用空间列表包含着相同大小的相互连接的块,而我们需要的是提供一种动态分配大小不同的内存块的方法。
Java中动态内存分配通常在堆内存中进行的,看下面一块称为堆的内存区域:

上图的堆内存区域中,包含着不同大小的内存块,它们是应分配请求而预留的,阴影部分为为分配的内存。
下面我们讨论动态分配内存请求的处理策略。一种方法是“最先适配”,另一种方法是“最佳适配”。
下图是上图显示的堆的另一幅图画:

在最先适配策略中,当我们发出动态分配内存的请求的时候,指针Avail从所指的块开始绕着由空闲块组成的环进行寻找一个块B,使得Size(B)>N(N为我们要申请的内存大小),如果B>N,则我们把B分成两块,一块大小为N,另一块大小为B2,大小为Size(B)-N。我们使用N来满足我们的请求,并把B2连接回到空闲块环中。如果刚好B=N,则这种情况称为精确适配。
在最佳适配策略中,当我们发出动态分配内存的请求的时候,指针Avail从所指的块开始绕着由空闲块组成的环进行寻找一个块B,只有找到精确适配的时候才停止。若没有找到精确适配,则我们就找最近的适配,按照最先适配策略方法进行分配。
上面只是简单的学习,有待更多更深入的学习。
本文介绍了早期编程语言中的内存管理技术,包括car和cdr域的概念、标记式类型的系统及其运行时解释型计算机制,以及垃圾收集的过程。此外还探讨了Java中动态内存分配的基本原理,包括堆内存的管理及最先适配和最佳适配两种分配策略。

1万+

被折叠的 条评论
为什么被折叠?



