跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

AIX 中的内存分配机制

Uma Chandolu, 软件工程师, IBM
http://www.ibm.com/developerworks/i/p-uchandolu.jpg
Uma M. Chandolu 是一名 AIX 上的开发支持专家。他目前是 IBM 班加罗尔的 AIX 安全开发支持团队的团队负责人。他拥有三年 AIX 环境中的广泛实践经验,并擅长于 AIX 系统管理和其他子系统。他拥有与客户合作和处理客户关键型情景的经验。
(An IBM developerWorks Contributing Author)
Gargi Srinivas, 系统软件工程师, IBM
http://www.ibm.com/developerworks/i/p-sgargi.jpg
Gargi Srinivas 是 IBM 的 AIX L3 开发人员。她在 AIX 用户空间组件方面有三年经验。

简介: 内存管理是操作系统最重要的职责之一。操作系统根据程序的请求把内存段分配给它们,当程序不再需要内存时释放内存以便重用。本文讨论 AIX® 上的各种内存管理分配算法及其特点。

发布日期: 2011 年 2 月 14 日
级别: 中级 原创语言: 英文
访问情况 : 4737 次浏览
评论: 


简介

分配策略 是指一套数据结构和算法,它们用来表示和管理堆,实现动态分配、释放和重新分配内存等内存管理功能。

AIX malloc 子系统支持以下分配策略:

  • 默认的 (Yorktown) 分配策略
  • Watson 分配策略
  • Malloc 3.1 分配策略

默认分配策略概述

AIX 中的默认分配策略也称为 Yorktown 策略。它按照 Cartesian 二分法检索树格式以节点的形式维护堆中的空闲空间。

节点按照地址从左到右排列(地址向右增加),按照长度从上到下排列(因此子节点不会比其父节点大)。


图 1. Yorktown 策略的 Cartesian 二分法检索树
Yorktown 图

什么时候应该使用 Yorktown

  • 在 AIX 上默认启用 Yorktown。它是所有分配策略中使用最广泛、最稳定的,因此适用于几乎所有情况。
  • 因为它采用树的形式,树中有不同大小的节点,所以对分配的块大小没有限制。

用以下命令启用 Yorktown:

export MALLOCTYPE=Yorktown

可以通过两种方法检查是否启用了 Yorktown:

  1. 使用 DBX 子命令 malloc
  2. 运行命令 echo $MALLOCTYPE

Yorktown 分配算法

分配的总内存 = roundup (n + prefix_size, alignment),其中:

  • n 等于用户请求的字节数
  • prefix_size 等于元数据信息

首先,删除空闲树中(大于或等于请求的块大小的)地址最低的节点。如果这个节点大于请求的内存量,就把它分为两块。多余的那一块返回给树,插入在空闲树中的适当位置。然后把请求的块返回给调用者。

Yorktown 释放算法

在释放内存时,需要把释放的节点插入到空闲树中。这采用标准的根插入算法。搜索树中的每个节点并与释放的节点进行比较,如果释放的节点的地址与任何其他节点相邻,它就与那个节点合并。合并相邻节点在一定程度上可以避免碎片化,因为如果树中散布着大量空闲节点,即使它们的地址相邻,连续分配也无法使用它们。

Yorktown 重新分配算法

如果重新分配的块大于原来的块,那么把原来的块返回给空闲树,以便与相邻的节点合并(如果可能的话)。然后,按请求的大小分配一个新的块。把数据从原来的块转移到新的块中,把新的块返回给调用者。原来的块被释放,不再有效。如果重新分配的块小于原来的块,那么把它分割开,多余的块返回给空闲树,请求的块返回给调用者。

Watson 分配策略概述

Watson 分配策略在两个单独的 “红黑树” 中以节点的形式维护堆中的空闲空间:

  1. 按地址排序
  2. 按大小排序

必须适当地维护这两个树以确保一致性和正确性。


图 2. Watson 分配策略中使用的基于 “按地址排序” 的红黑树
Watson 1 图

地址树中每个节点的地址都比左边子树中的节点低,比右边子树中的节点高。


图 3. Watson 分配策略中使用的基于 “按大小排序” 的红黑树
Watson 2 图

大小树中的每个节点都比左边子树中的节点小,比右边子树中的节点大。

什么时候应该使用 Watson

因为 Watson 在红黑树中维护空间,所以与其他策略相比,它提供更高效的插入和搜索等树操作。

用以下命令启用它:

export MALLOCTYPE=Watson 

Watson 分配算法

与 Yorktown 策略相似,Watson 搜索大小树,寻找符合请求的最小的块。如果在大小树中找到的块正好是请求的大小,那么从大小树和地址树中删除这个块并返回给调用者。

如果在空闲树中没有找到足够大的块,那么使用 sbrk() 系统调用扩展进程堆,把扩展后的块添加到大小树和地址树中,然后像以前一样继续分配。

Watson 释放算法

节点首先返回到地址树的根上。在树中移动,检查此节点是否与树中的任何节点地址相邻。如果有相邻节点,那么释放的节点与树中的节点合并。以这种方式合并节点可以避免堆内存碎片化。

Watson 重新分配算法

如果重新分配的块大于原来的块,那么把原来的块返回给空闲树,以便与相邻的节点合并(如果可能的话)。然后,按请求的大小分配一个新的块。把数据从原来的块转移到新的块中,把新的块返回给调用者。如果重新分配的块小于原来的块,那么把它分割开,多余的块返回给空闲树,请求的块发送给调用者。

malloc 3.1 分配策略概述

在 malloc 3.1 中,以散列 bucket 的形式维护堆内存,每个 bucket 指向一个链表,每个链表只包含特定大小的节点或块。使用以下公式计算块的大小(i 表示 bucket 编号):

大小 = 2 ^ (i + 4)


图 4. 在 malloc 3.1 中以散列 bucket 的形式维护堆内存
Malloc 3.1 图

用以下命令启用 malloc:

export MALLOCTYPE=3.1 (对于 32 位程序) 
export MALLOCTYPE=3.1_64BIT (对于 64 位程序)

Malloc 3.1 分配算法

当从空闲池分配块时,首先使用以下公式把请求的字节数转换为 bucket 数组索引:

needed = requested + 8
If needed <= 16,
then
bucket = 0
If needed  >16,
then
bucket = (log(needed)/log(2) rounded down to the nearest integer) - 3

bucket 指向的链表中每个块的大小为 2 ^ (bucket + 4)。如果 bucket 中的链表是空的,就使用 sbrk() 子例程向其中添加块。如果空闲链表非空,那么把链表开头的块返回给调用者。链表中的下一个块成为新的链表头。

Malloc 3.1 释放算法

当把内存块返回给空闲池时,像分配时一样计算 bucket 索引。然后,把释放的节点添加到这个 bucket 的空闲链表的开头。

Malloc 3.1 重新分配算法

在重新分配时,比较请求的大小和已分配块的大小。因为每个 bucket 处理的块大小差异很大,新的块大小可能属于与原来的块相同的 bucket 的处理范围。在这种情况下,返回相同的块。如果所需的大小大于现有的块,那么释放这个块,从另一个 bucket 分配一个新的块,把数据从原来的块转移到新的块中。

Malloc 3.1 的局限性

malloc 分配策略的效率比默认分配策略低,对于大多数情况不建议采用这种策略。这种策略把分配请求的大小向上取整到下一个可用的块大小。因此,分配的内存可能比需要量多。

有时候,应用程序可能会不知不觉地依赖于 malloc 3.1 分配策略的副作用。例如,假设一个程序会错误地覆盖 malloc 已经分配的字节。当使用 malloc 3.1 分配策略时,它可能能够正确地运行,因为从本质上说 3.1 策略可能分配超过请求量的内存。当采用其他分配策略时,这个程序应该会运行失败。

但是,在某些情况下,3.1 策略的性能可能比其他分配算法好。这是因为它最初分配了超过实际请求量的内存,所以可以减少重新分配期间的数据转移开销。

其他 malloc 选项

其他 malloc 选项包括:

  • malloc multiheap
  • pool allocation
  • malloc buckets

malloc multiheap

在默认情况下,malloc 子系统把整个进程堆当作单一实体。在多线程环境中,多个线程访问同一个堆。在这种场景中,使用单一堆是非常低效的,因为在为一个线程服务时它会取得堆锁,其他线程不得不等待轮到它们访问堆。对于这种情况,这个选项是有意义的。

使用以下命令启用 multiheap 选项:

MALLOCOPTIONS=[multiheap:n] | [considersize] 

下面说明选项的作用:

  • multiheap:n
    malloc multiheap 可分配的最大堆数量是 32。可以通过指定 1 到 32 的数字指定允许分配的堆数量。
  • considersize
    在默认情况下,malloc multiheap 选择下一个可用的堆。如果指定 considersize 选项,malloc multiheap 会使用不同的算法,选择空闲空间足以处理请求的堆。

malloc multiheap 的局限性

  • 因为单一堆实际上被分割为许多个堆(最多 32 个),不必要地启用 malloc multiheap 会导致严重的碎片化。它还会导致系统看起来内存耗尽的情况,因为可用的内存碎片化,没有连续的可用内存。
  • 因为 considersize 选项需要额外的处理,使用此选项可能会在一定程度上降低进程的性能。
  • 对于 malloc 3.1 和用户定义的分配策略,不支持 multiheap 选项。

pool allocation

对于小于或等于 512 字节的内存块,AIX malloc 为 malloc 的实际后端功能提供更高效的前端。pool allocation 为每个线程创建它自己的 malloc 池,以此避免与其他线程发生锁争用。目前,对于这个分配器,每个进程的最大池大小限制为 512MB。

使用以下命令启用 pool allocation:

MALLOCOPTIONS=pool<:max_size>

这会创建固定数量的大小增加的池。32 位应用程序有 128 个池,64 位应用程序有 64 个池。

如果应用程序的一个线程分配内存,而其他线程释放内存,那么 pool allocation 实际上是无效的。

malloc buckets

malloc buckets 是 Yorktown 分配策略的扩展。当应用程序有许多小的分配请求时,经常使用 malloc buckets。它的主要作用是避免过分碎片化,因为它把所有小内存块集中在一个地方。此选项只能与 Yorktown 分配策略一起使用。

使用以下命令启用 malloc buckets:

MALLOCOPTIONS=buckets,number_of_buckets:n

bucket 分配器只能处理最大 512 字节的分配请求,更大的分配请求自动地转发给 Yorktown malloc。

结束语

本文讨论了各种 AIX 内存分配方案的基本原理及其特点。全面了解各种分配方案有助于您选择最适合自己应用程序的分配方案,从而实现最好的执行效率和性能。


参考资料

学习

  • AIX 信息中心提供关于 system memory allocation using malloc subsystemmalloc multiheapmalloc buckets 的更多信息。

  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。

  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。

  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。

  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。

  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。

  • developerWorks 技术活动网络广播:随时关注 developerWorks 技术活动和网络广播。

获得产品和技术

  • 以最适合您的方式 评估 IBM 产品:下载产品试用版,在线试用产品,在云环境下试用产品,或者在 SOA Sandbox 中花费几个小时来学习如何高效地实现 Service Oriented Architecture。

讨论

作者简介

http://www.ibm.com/developerworks/i/p-uchandolu.jpg developerWorks 投稿作者

Uma M. Chandolu 是一名 AIX 上的开发支持专家。他目前是 IBM 班加罗尔的 AIX 安全开发支持团队的团队负责人。他拥有三年 AIX 环境中的广泛实践经验,并擅长于 AIX 系统管理和其他子系统。他拥有与客户合作和处理客户关键型情景的经验。

http://www.ibm.com/developerworks/i/p-sgargi.jpg

Gargi Srinivas 是 IBM 的 AIX L3 开发人员。她在 AIX 用户空间组件方面有三年经验。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=626611
ArticleTitle=AIX 中的内存分配机制
publish-date=02142011
author1-email=uchandol@in.ibm.com
author1-email-cc=
author2-email=gargi.srinivas_cnnew1@in.ibm.com
author2-email-cc=

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。