zoukankan      html  css  js  c++  java
  • Erlang模块erts_alloc

    C库

            erts_alloc

    库摘要

            Erlang运行时系统内部内存分配器库。

    描述

            erts_alloc是一个Erlang运行时系统内部内存分配器库。 erts_alloc为Erlang运行时系统提供了许多内存分配器。

    分配器

            存在以下分配器:

    temp_alloc

    用于临时分配的分配器。

    eheap_alloc

    用于Erlang堆数据(例如Erlang进程堆)的分配器。

    binary_alloc

    用于Erlang二进制数据的分配器。

    ets_alloc

    用于ets数据的分配器。

    driver_alloc

    用于驱动程序数据的分配器。

    literal_alloc

    用于Erlang代码中常数项的分配器。

    sl_alloc

    用于预期寿命短的内存块的分配器。

    ll_alloc

    用于预期寿命长的内存块的分配器,例如,Erlang代码。

    fix_alloc

    一种快速分配器,用于某些常用的固定大小的数据类型。

    exec_alloc

    HiPE应用程序用于本机可执行代码的分配器。

    std_alloc

    未用于通过上述任何其他分配器分配的大多数内存块的分配器。

    sys_alloc

    通常,这是特定操作系统上使用的默认malloc实现。

    mseg_alloc

    内存段分配器。其他分配器使用它来分配内存段,并且仅在具有mmap系统调用的系统上可用。被释放的内存段在销毁之前会在段缓存中保留一段时间。分配段后,将尽可能使用缓存的段,而不是创建新的段。这样可以减少进行系统调用的次数。

            sys_alloc,literal_alloc和temp_alloc始终启用,不能禁用。 exec_alloc仅在需要时可用,不能禁用。 如果可用,并且启用了使用它的分配器,则始终启用mseg_alloc。 所有其他分配器都可以启用或禁用。 默认情况下,所有分配器都是启用的。 禁用分配器后,将使用sys_alloc代替禁用的分配器。

            erts_alloc库的主要思想是将不同使用的内存块分离到不同的内存区域,以减少内存碎片。 与为那些不那么频繁分配的内存块相比,通过花更少的精力找到适合于频繁分配的内存块的性能,可以实现性能提升。

    alloc_util框架

            在内部,称为alloc_util的框架用于实现分配器。 sys_alloc和mseg_alloc不使用此框架,因此以下内容不适用于它们。

            分配器管理多个区域,这些区域称为载体,在其中放置了内存块。 载体可以放在单独的内存段中(通过mseg_alloc分配),也可以放在堆段中(通过sys_alloc分配)。

    • 多块载体用于存储几个块。
    • 单块载体用于存储一个块。
    • 大于单块载体阈值(sbct)参数值的块将放置在单块载体中。
    • 小于参数sbct的值的块将放置在多块载体中。

            通常,分配器创建“主多块载体”。 主多块载体永远不会释放。 主多块载体的大小由参数mmbcs的值确定。

            通过mseg_alloc分配的多块载体的大小取决于以下参数:

            如果nc是分配器管理的当前多块载体数(不包括主多块载体),则当nc<=mbcgs时,此分配器分配的下一个mseg_alloc多块载体的大小约为smbcs + nc *(lmbcs-smbcs)/ mbcgs,nc> mbcgs时,为lmbcs。 但是,如果参数sbct的值大于参数lmbcs的值,则分配器可能必须创建大于参数lmbcs的值的多块载体。 通过mseg_alloc分配的单块载体大小为整页。

            通过sys_alloc分配的载体大小取决于sys_alloc载体大小(ycs)参数的值。 载体的大小是满足请求的参数ycs的值的最小倍数。

            空闲块的合并始终立即执行。 使用自由块中的边界标记(页眉和页脚),这使得合并的时间复杂度恒定。

            可以使用参数as配置分配器用于多块载波的内存分配策略。 可以使用以下策略:

    Best fit

    策略:查找满足请求块大小的最小块。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的大小数。

    Address order best fit

    策略:查找满足请求块大小的最小块。 如果找到多个块,则选择地址最低的那个。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的数量。

    Address order first fit

    策略:查找地址满足要求的块大小最低的块。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的数量。

    Address order first fit carrier best fit

    策略:找到地址最低且可满足请求的块大小的载体,然后使用“最适合”策略在该载体内找到一个块。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的数量。

    Address order first fit carrier address order best fit

    策略:找到可满足请求块大小的最低地址的载体,然后使用“地址顺序最适合”策略在该载体中找到一个块。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的数量。

    Age order first fit carrier address order first fit

    策略:找到可以满足请求的块大小的最早的载体,然后使用“地址顺序优先”策略在该载体中找到一个块。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的数量。

    Age order first fit carrier best fit

    策略:找到可以满足请求的块大小的最早的载体,然后使用“最适合”策略在该载体中找到一个块。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的数量。

    Age order first fit carrier address order best fit

    策略:找到可以满足请求的块大小的最早的载体,然后使用“地址顺序最适合”策略在该载体中找到一个块。

    实现:使用平衡的二进制搜索树。 时间复杂度与log N成正比,其中N是空闲块的数量。

    Good fit

    策略:尝试找到最合适的,但要在有限的搜索中找到最合适的。

    实现:该实现使用最大块搜索深度(在每个列表中)的隔离的空闲列表来快速找到合适的对象。 当最大块搜索深度较小时(默认为3),此实现的时间复杂度是恒定的。 可以使用参数mbsd配置最大块搜索深度。

    A fit

    策略:不要寻找合适的位置,仅检查一个空闲块以查看其是否满足要求。 此策略仅用于临时分配。

    实现:检查空闲列表中的第一个块。 如果满足请求,则使用该请求,否则创建新的载体。 该实现具有恒定的时间复杂度。

    从ERTS 5.6.1开始,仿真器拒绝在temp_alloc之外的其他分配器上使用此策略。 这是因为它只会给其他分配器带来问题。

            除了上述普通分配器之外,一些预分配器还用于某些特定的数据类型。 运行系统启动时,这些预分配器会为某些数据类型预分配固定数量的内存。 只要有预分配的内存可用,就可以使用它。 当没有可用的预分配内存时,将在普通分配器中分配内存。 这些预分配器通常比普通分配器快得多,但只能满足有限数量的请求。

    影响erts_alloc的系统标志

    警告:仅在确定自己在做什么时才使用这些标志。 不合适的设置可能会导致严重的性能下降,甚至在运行期间的任何时间导致系统崩溃。

            内存分配器系统标志具有以下语法:+ M <S> <P> <V>,其中<S>是标识子系统的字母,<P>是参数,而<V>是要使用的值。 可以将这些标志作为命令行参数传递给Erlang仿真器(erl(1))。

            影响特定分配器的系统标志的大写字母为<S>。 以下字母用于分配器:

    B: binary_alloc

    D: std_alloc

    E: ets_alloc

    F: fix_alloc

    H: eheap_alloc

    I: literal_alloc

    L: ll_alloc

    M: mseg_alloc

    R: driver_alloc

    S: sl_alloc

    T: temp_alloc

    X: exec_alloc

    Y: sys_alloc

    mseg_alloc的配置标志

    +MMamcbf <size>

            绝对最大高速缓存不合适(以千字节为单位)。 如果内存段缓存中的某个段的大小超过了所请求的大小且大于此参数的值,则不会重用该段。 默认为4096。

    +MMrmcbf <ratio>

            相对最大高速缓存不合适(百分比)。 如果内存段缓存中的某个段的大小超过了请求的大小,并且超过了请求大小的相对最大缓存不适合百分比,则该段不会被重用。 默认为20。

    +MMsco true|false

            设置仅超级载体标志。 默认为true。 当使用超级载体且此标志为true时,mseg_alloc仅在超级载体中创建载体。 请注意,alloc_util框架可以创建sys_alloc载体,因此,如果要在超级载体中创建所有载体,则希望通过传递+ Musac false来禁用sys_alloc载体的使用。 当该标志为false时,当超级载体已满时,mseg_alloc尝试在超级载体之外创建载体。

    注意:并非所有系统都支持将此标志设置为false。 该标志然后被忽略。

    +MMscrfsd <amount>

            设置超级载体保留的自由段描述符。 默认值为65536。此参数确定为超级载体使用的空闲段描述符保留的内存量。 如果系统用完了空闲段描述符的保留内存,则将使用其他内存。 但是,这可能会导致碎片问题,因此您要确保这种情况永远不会发生。 可以从调用erlang:system_info({allocator,mseg_alloc})的结果的erts_mmap元组部分中检索使用的最大空闲段描述符数量。

    +MMscrpm true|false

            设置超级载体保留物理内存标志。 默认为true。 当此标志为true时,物理内存在创建时将立即为整个超级载体保留。 此后保留保留不变。 当此标志设置为false时,在创建时仅为超级载体保留虚拟地址空间。 系统尝试在超级载体中创建载体时保留物理内存,并尝试在超级载体中破坏载体时取消物理内存。

    注意:

    物理内存的保留意味着什么,在很大程度上取决于操作系统及其配置。 例如,Linux上不同的内存过量使用设置会极大地改变行为。

    并非所有系统都支持将此标志设置为false。 该标志然后被忽略。

    +MMscs <size in MB>

            设置超级载体大小(以MB为单位)。 默认为0,即默认情况下禁用超级载体。 超级载体是虚拟地址空间中的一个大连续区域。 如果存在,则mseg_alloc始终尝试在超级载体中创建新载体。 注意,alloc_util框架可以创建sys_alloc载体。 有关更多信息,请参见+ MMsco。

    +MMmcs <amount>

            最大缓存段。 存储在内存段缓存中的最大内存段数。 有效范围是[0,30]。 默认为10。

    用于配置sys_alloc的标志

    +MYe true

            启用sys_alloc。

    注意:sys_alloc无法禁用。

    +MYm libc

            要使用的malloc库。 仅libc可用。 libc启用标准libc malloc实现。 默认情况下使用libc。 

    +MYtt <size>

            修剪阈值大小(以千字节为单位)。 这是malloc(不释放给操作系统)保留的堆(由sbrk分配)顶部的最大可用内存量。 当堆顶部的可用内存量超过修剪阈值时,malloc释放它(通过调用sbrk)。 修剪阈值以千字节为单位指定。 默认值为128。

    注意:仅当仿真器与GNU C库链接并使用其malloc实现时,此标志才有效。

    +MYtp <size>

            Top pad大小(以千字节为单位)。 这是当调用sbrk从操作系统获取更多内存时,malloc分配的额外内存量。 预设为0。

    注意:仅当仿真器与GNU C库链接并使用其malloc实现时,此标志才有效。

    基于alloc_util的分配器配置标志

            如果将u用作子系统标识符(即<S> = u),则所有基于alloc_util的分配器都会生效。 如果将B,D,E,F,H,L,R,S或T用作子系统标识符,则仅实现特定的分配器标识符。

    +M<S>acul <utilization>|de

            放弃载体利用率限制。有效的<utilization>是[0,100]范围内的整数,以百分比表示利用率。使用利用率值> 0时,允许分配器实例放弃多块载体。如果传递了de(默认启用)而不是<utilization>,则使用建议的非零利用率值。选择的值取决于分配器类型,并且可以在ERTS版本之间进行更改。默认为de,但是将来可以更改。

            当分配器实例中的内存利用率低于所使用的利用率值时,将放弃载体。一旦放弃了载体,便不会在其中进行新的分配。当分配器实例获得增加的多块载体需求时,它首先尝试从相同分配器类型的分配器实例中获取废弃的载体。如果无法获取任何废弃的载体,则会创建一个新的空载体。提取废弃的载体后,它将充当普通载体。此功能对使用的分配策略有特殊要求。仅策略aoff,aoffcbf,aoffcaobf,ageffcaoffm,ageffcbf和ageffcaobf支持废弃的载体。

            此功能还需要启用多个线程特定的实例。启用此功能时,如果尚未启用多个特定于线程的实例,则启用该功能;如果当前策略不支持废弃的载体,则启用aoffcbf策略。可以在所有基于alloc_util框架的分配器上启用此功能,但temp_alloc除外(这将毫无意义)。

    +M<S>acfml <bytes>

            放弃无载体最小限制。 有效的<bytes>是表示块大小限制的正整数。 载体中最大的空闲块必须至少为字节大,以便放弃该载体。 默认值为零,但将来可以更改。

            另请参阅acul。

    +M<S>acnl <amount>

            放弃载体数量限制。 有效的<amount>是一个正整数,代表每个分配器实例的最大被放弃载体数。 默认值为1000,实际上将禁用该限制,但是以后可以更改。

            另请参阅acul。

    +M<S>as bf|aobf|aoff|aoffcbf|aoffcaobf|ageffcaoff|ageffcbf|ageffcaobf|gf|af

            分配策略。 以下策略是有效的:

    • bf (best fit)
    • aobf (address order best fit)
    • aoff (address order first fit)
    • aoffcbf (address order first fit carrier best fit)
    • aoffcaobf (address order first fit carrier address order best fit)
    • ageffcaoff (age order first fit carrier address order first fit)
    • ageffcbf (age order first fit carrier best fit)
    • ageffcaobf (age order first fit carrier address order best fit)
    • gf (good fit)
    • af (a fit)

            请参阅“ alloc_util框架”一节中的分配策略说明。

    +M<S>asbcst <size>

            绝对单个块载体收缩阈值(以千字节为单位)。 当缩小mseg_alloc单个块载体中的某个块时,如果未使用的内存量小于此阈值,则该载体保持不变,否则缩小该载体。 另请参见rsbcst。

    +M<S>atags true|false

            在每个分配的块中添加一个小标签,其中包含有关其内容和分配人的基本信息。 使用仪器模块检查此信息。

            启用时,运行时开销是每个分配一个字。 将来可能会随时更改。

            对于binary_alloc和driver_alloc,默认值为true;对于其他分配器类型,默认值为false。

    +M<S>e true|false

            启用分配器<S>。

    +M<S>lmbcs <size>

            最大(mseg_alloc)多块载体大小(以千字节为单位)。 请参阅“ alloc_util框架”部分中有关如何确定mseg_alloc多块载体的大小的说明。 在32位Unix风格的操作系统上,此限制不能设置为> 128 MB。

    +M<S>mbcgs <ratio>

            (mseg_alloc)多块载体增长阶段。 请参阅“ alloc_util框架”部分中有关如何确定mseg_alloc多块载体的大小的说明。

    +M<S>mbsd <depth>

            最大块搜索深度。 仅当为分配器<S>选择了合适策略时,此标志才有效。 使用良好拟合策略时,会将空闲块放置在单独的空闲列表中。 每个空闲列表都包含特定范围内的大小块。 最大块搜索深度设置了在搜索满足请求的合适块期间在自由列表中要检查的最大块数的限制。

    +M<S>mmbcs <size>

            主多块载体大小。 设置分配器<S>的主多块载体的大小。 主多块载体通过sys_alloc分配,并且永不释放。

    +M<S>mmmbc <amount>

            最大mseg_alloc多块载体。 分配器<S>通过mseg_alloc分配的最大多块载体数。 达到此限制后,将通过sys_alloc分配新的多块载体。

    +M<S>mmsbc <amount>

            最大mseg_alloc单块载体。 分配器<S>通过mseg_alloc分配的最大单块载体数。 达到此限制后,将通过sys_alloc分配新的单块载体。

    +M<S>ramv <bool>

            重新分配总是移动。 启用后,重新分配操作或多或少会转换为分配,复制,自由序列。 这通常可以减少内存碎片,但会降低性能。

    +M<S>rmbcmt <ratio>

            相对多块载体移动阈值(以百分比为单位)。 当缩小位于多块载体中的块时,如果返回的内存的大小与先前大小之比大于此阈值,则移动该块,否则将在当前位置缩小该块。

    +M<S>rsbcmt <ratio>

            相对单个块载体移动阈值(以百分比为单位)。 当位于单块载体中的块缩小到小于参数sbct的大小时,如果未使用内存的比率小于此阈值,则该块在单块载体中保持不变,否则将其移入多块载体 。

    +M<S>rsbcst <ratio>

            相对单个块载体收缩阈值(以百分比为单位)。 当缩小mseg_alloc单个块载体中的一个块时,如果未使用内存的比率小于此阈值,则该载体将保持不变,否则该载体将被缩小。 另请参见asbcst。

    +M<S>sbct <size>

            单块载体阈值(以千字节为单位)。 大于此阈值的块将放置在单块载体中。 小于此阈值的块将放置在多块载体中。 在32位Unix风格的操作系统上,此阈值不能设置为> 8 MB。

    +M<S>smbcs <size>

            最小(mseg_alloc)多块载体大小(以千字节为单位)。 请参阅“ alloc_util框架”部分中有关如何确定mseg_alloc多块载体的大小的说明。

    +M<S>t true|false

            分配器的多个线程特定实例。 此选项仅对具有SMP支持的运行时系统有效。 具有SMP支持的运行时系统上的默认行为是NoSchedulers + 1实例。 每个调度程序使用其自己的无锁实例,其他线程使用一个公共实例。

            在ERTS 5.9之前,可以配置比调度程序更少数量的线程特定实例。 但是,这不再可能。

    配置alloc_util的标志

            所有基于alloc_util的分配都会受到影响。

    +Muycs <size>

            sys_alloc载体大小。 通过sys_alloc分配的载体的大小是sys_alloc载体大小的倍数。 但是,对于主多块载体和在内存不足期间分配的载体,情况并非如此。

    +Mummc <amount>

            最大mseg_alloc载体。 放置在单独的内存段中的最大载体数。 达到此限制后,新的载体将放置在从sys_alloc检索的内存中。

    +Musac <bool>

            允许sys_alloc载体。 默认为true。 如果设置为false,则分配器决不会使用alloc_util框架创建sys_alloc载体。

    literal_alloc的特殊标志

    +MIscs <size in MB>

            literal_alloc超级载体大小(以MB为单位)。 在64位体系结构上为Erlang代码中的字面量保留的虚拟地址空间量。 默认为1024(即1 GB),通常就足够了。 该标志在32位体系结构上被忽略。

    仪表标志

    +M<S>atags

            在每个分配的块中添加一个小标签,其中包含有关其内容和分配人的基本信息。 请参阅+ M <S>标记以获取更完整的描述。

    +Mit X

            保留以备将来使用。 不要使用此标志。

    注意:启用模拟器检测后,模拟器将使用更多内存,并且运行速度会更慢。

    其他标志

    +Mea min|max|r9c|r10b|r11b|config

    选项:

    min

            禁用所有可以禁用的分配器。

    max

            启用所有分配器(默认)。

    r9c | r10b | r11b

            按照在相应的Erlang / OTP版本中配置的所有分配器进行配置。 这些将最终被删除。

    config

            禁用使用erts_alloc_config(3)创建分配器配置时无法启用的功能。

    注意:此选项仅在运行erts_alloc_config(3)时使用,而在使用创建的配置时不可用。

    +Mlpm all|no

            锁定物理内存。 默认为否,即没有物理内存被锁定。 如果设置为all,则运行时系统进行的所有内存映射都将锁定到物理内存中。 如果设置为all,则如果不支持此功能,用户没有足够的特权或者不允许用户锁定足够的物理内存,则运行时系统将无法启动。 如果达到了用户对锁定内存量的限制,则运行时系统也会因内存不足而失败。

    笔记

            此处仅提供了一些默认值。 有关当前使用的设置以及分配器的当前状态的信息,请参见erlang:system_info(allocator)和erlang:system_info({allocator,Alloc})。

    注意:

    这些标志大多数都高度依赖于实现,可以更改或删除而无需事先通知。

    erts_alloc没有义务严格使用已传递给它的设置(它甚至可以忽略它们)。

            erts_alloc_config(3)工具可用于帮助创建适用于有限数量的运行时场景的erts_alloc配置。

    也可以看看

            erl(1), erlang(3), erts_alloc_config(3), instrument(3)
    <blockquote><p>相关阅读:</p>
    <p>成版人抖音</p>
    <p><li>抖音的推送机制是怎样的?</p>
    <p>抖音小程序在哪里添加包括苹果版</p>
    <p><li class="">抖音运营</p>

  • 相关阅读:
    面试题(三)
    面试题(二)
    经典面试题(一)
    $.ajax()实现简单计算器
    [hdu5373 The shortest problem]模拟
    [hdu5371 Hotaru's problem]最大回文半径
    [hdu5372 Segment Game]树状数组
    [zoj3813]Alternating Sum 公式化简,线段树
    [hdu5348]图上找环,删环
    [hdu5360]贪心
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309200.html
Copyright © 2011-2022 走看看