mi-malloc 1.8/2.1
 
正在加载...
正在搜索...
无匹配项
扩展功能

扩展功能。更多...

#define MI_SMALL_SIZE_MAX
 mi_malloc_smallmi_zalloc_small 中允许的小型分配的最大大小(通常为 128*sizeof(void*) (= 64 位系统上为 1KB))
 

类型定义

typedef void mi_deferred_free_fun(bool force, unsigned long long heartbeat, void *arg)
 延迟释放函数的类型。
 
typedef void mi_output_fun(const char *msg, void *arg)
 输出函数的类型。
 
typedef void mi_error_fun(int err, void *arg)
 错误回调函数的类型。
 
typedef int mi_arena_id_t
 Mimalloc 使用操作系统提供的大型(虚拟)内存区域,称为“arena”,来管理其内存。
 
typedef void * mi_subproc_id_t
 进程可以将线程与子进程关联起来。
 

函数

void * mi_malloc_small (size_t size)
 分配一个小型对象。
 
void * mi_zalloc_small (size_t size)
 分配一个零初始化的小型对象。
 
size_t mi_usable_size (void *p)
 返回内存块中可用的字节数。
 
size_t mi_good_size (size_t size)
 返回使用的分配大小。
 
void mi_collect (bool force)
 积极释放内存。
 
void mi_stats_print (void *out)
 已弃用。
 
void mi_stats_print_out (mi_output_fun *out, void *arg)
 打印主要统计信息。
 
void mi_stats_reset (void)
 重置统计信息。
 
void mi_stats_merge (void)
 将线程本地统计信息与主要统计信息合并并重置。
 
void mi_thread_init (void)
 在线程上初始化 mimalloc。
 
void mi_thread_done (void)
 在线程上取消初始化 mimalloc。
 
void mi_thread_stats_print_out (mi_output_fun *out, void *arg)
 打印此线程的堆统计信息。
 
void mi_register_deferred_free (mi_deferred_free_fun *deferred_free, void *arg)
 注册延迟释放函数。
 
void mi_register_output (mi_output_fun *out, void *arg)
 注册输出函数。
 
void mi_register_error (mi_error_fun *errfun, void *arg)
 注册错误回调函数。
 
bool mi_is_in_heap_region (const void *p)
 指针是否属于我们的堆区域?
 
int mi_reserve_os_memory (size_t size, bool commit, bool allow_large)
 为 mimalloc 保留操作系统内存。
 
bool mi_manage_os_memory (void *start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node)
 管理特定内存区域供 mimalloc 使用。
 
int mi_reserve_huge_os_pages_interleave (size_t pages, size_t numa_nodes, size_t timeout_msecs)
 numa_nodes 个节点上平均分配 pages 个巨大的操作系统页面(1GiB),但最多在 timeout_msecs 毫秒后停止。
 
int mi_reserve_huge_os_pages_at (size_t pages, int numa_node, size_t timeout_msecs)
 在特定的 numa_node 上保留 pages 个巨大的操作系统页面(1GiB),但最多在 timeout_msecs 毫秒后停止。
 
bool mi_is_redirected ()
 C 运行时 malloc API 是否被重定向?
 
void mi_process_info (size_t *elapsed_msecs, size_t *user_msecs, size_t *system_msecs, size_t *current_rss, size_t *peak_rss, size_t *current_commit, size_t *peak_commit, size_t *page_faults)
 返回进程信息(时间与内存使用)。
 
void mi_debug_show_arenas (bool show_inuse, bool show_abandoned, bool show_purge)
 显示所有当前 arena。
 
void * mi_arena_area (mi_arena_id_t arena_id, size_t *size)
 返回 arena 的大小。
 
int mi_reserve_huge_os_pages_at_ex (size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t *arena_id)
 将巨大的操作系统页面(1GiB)保留到单个 arena 中。
 
int mi_reserve_os_memory_ex (size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t *arena_id)
 保留操作系统内存以在 arena 中管理。
 
bool mi_manage_os_memory_ex (void *start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t *arena_id)
 将外部分配的内存作为 mimalloc arena 进行管理。
 
mi_heap_tmi_heap_new_in_arena (mi_arena_id_t arena_id)
 创建一个只在指定 arena 中分配的新堆。
 
mi_heap_tmi_heap_new_ex (int heap_tag, bool allow_destroy, mi_arena_id_t arena_id)
 创建一个新堆。
 
mi_subproc_id_t mi_subproc_main (void)
 获取主子进程标识符。
 
mi_subproc_id_t mi_subproc_new (void)
 创建一个新的子进程(尚未关联任何线程)。
 
void mi_subproc_delete (mi_subproc_id_t subproc)
 删除之前创建的子进程。
 
void mi_subproc_add_current_thread (mi_subproc_id_t subproc)
 将当前线程添加到给定的子进程。
 

详细描述

扩展功能。

宏定义文档

◆ MI_SMALL_SIZE_MAX

#define MI_SMALL_SIZE_MAX

mi_malloc_smallmi_zalloc_small 中允许的小型分配的最大大小(通常为 128*sizeof(void*) (= 64 位系统上为 1KB))

类型定义文档

◆ mi_arena_id_t

typedef int mi_arena_id_t

Mimalloc 使用操作系统提供的大型(虚拟)内存区域,称为“arena”,来管理其内存。

每个 arena 都有一个关联的标识符。

◆ mi_deferred_free_fun

typedef void mi_deferred_free_fun(bool force, unsigned long long heartbeat, void *arg)

延迟释放函数的类型。

参数
force如果为 true,则所有未处理的项都应被释放。
heartbeat单调递增的计数。
arg注册时传入的参数,用于保存额外状态。
另请参见
mi_register_deferred_free

◆ mi_error_fun

typedef void mi_error_fun(int err, void *arg)

错误回调函数的类型。

参数
err错误代码(完整列表请参见 mi_register_error())。
arg注册时传入的参数,用于保存额外状态。
另请参见
mi_register_error()

◆ mi_output_fun

typedef void mi_output_fun(const char *msg, void *arg)

输出函数的类型。

参数
msg要输出的消息。
arg注册时传入的参数,用于保存额外状态。
另请参见
mi_register_output()

◆ mi_subproc_id_t

typedef void* mi_subproc_id_t

进程可以将线程与子进程关联起来。

子进程不会从其他子进程(被放弃的堆/线程)中回收内存。

函数文档

◆ mi_arena_area()

void * mi_arena_area ( mi_arena_id_t arena_id,
size_t * size )

返回 arena 的大小。

参数
arena_idarena 标识符。
size返回的(虚拟)arena 区域的字节大小。
返回
arena 的基地址。

◆ mi_collect()

void mi_collect ( bool force)

积极释放内存。

参数
force如果为 true,则积极将内存返回给操作系统(可能很昂贵!)

常规代码不应该调用此函数。在非常狭窄的情况下,它可能是有益的;特别是,当一个长时间运行的线程分配了大量由其他线程释放的块时,不时调用此函数可能会提高资源利用率。

◆ mi_debug_show_arenas()

void mi_debug_show_arenas ( bool show_inuse,
bool show_abandoned,
bool show_purge )

显示所有当前 arena。

参数
show_inuse显示正在使用的 arena 块。
show_abandoned显示被放弃的 arena 块。
show_purge显示计划清除的 arena 块。

◆ mi_good_size()

size_t mi_good_size ( size_t size)

返回使用的分配大小。

参数
size所需的最小字节大小。
返回
将要分配的大小 n,其中 n >= size

通常,mi_usable_size(mi_malloc(size)) == mi_good_size(size)。这可以用于在分配缓冲区时减少内部浪费的空间。

另请参见
mi_usable_size()

◆ mi_heap_new_ex()

mi_heap_t * mi_heap_new_ex ( int heap_tag,
bool allow_destroy,
mi_arena_id_t arena_id )

创建一个新堆。

参数
heap_tag与此堆关联的堆标签;堆只在具有相同标签的堆之间回收内存。
allow_destroy是否允许 mi_heap_destroy?不允许此操作可使堆从已终止的线程中回收内存。
arena_id如果非 0,则堆只从指定的 arena 中分配。
返回
一个新的堆,失败时为 NULL

arena_id 可被运行时用于只在指定的预留 arena 中分配。例如,这在 Koka 中用于压缩指针堆。heap_tag 使得堆可以将特定类型的对象隔离到具有该标签的堆中。例如,这在 CPython 集成中得到使用。

◆ mi_heap_new_in_arena()

mi_heap_t * mi_heap_new_in_arena ( mi_arena_id_t arena_id)

创建一个只在指定 arena 中分配的新堆。

参数
arena_idarena 标识符。
返回
新堆或 NULL

◆ mi_is_in_heap_region()

bool mi_is_in_heap_region ( const void * p)

指针是否属于我们的堆区域?

参数
p要检查的指针。
返回
如果这是指向我们堆的指针,则为 true。此函数相对较快。

◆ mi_is_redirected()

bool mi_is_redirected ( )

C 运行时 malloc API 是否被重定向?

返回
如果所有 malloc API 调用都被重定向到 mimalloc,则为 true

目前仅在 Windows 上使用。

◆ mi_malloc_small()

void * mi_malloc_small ( size_t size)

分配一个小型对象。

参数
size大小(以字节为单位),最多可为 MI_SMALL_SIZE_MAX
返回
指向至少 size 字节的新分配内存的指针,如果内存不足则为 NULL。此函数旨在用于运行时系统以获得最佳性能,并且不检查 size 是否确实很小 - 请谨慎使用!

◆ mi_manage_os_memory()

bool mi_manage_os_memory ( void * start,
size_t size,
bool is_committed,
bool is_large,
bool is_zero,
int numa_node )

管理特定内存区域供 mimalloc 使用。

这就像 mi_reserve_os_memory,只是该区域应该已经以某种方式分配并可供 mimalloc 使用。

参数
start内存区域的起始地址
size内存区域的大小。
is_committed该区域是否已提交?
is_large它是否由大型操作系统页面组成?对于不应取消提交或保护的内存(如 rdma 等),也将其设置为 true
is_zero该区域是否由零组成?
numa_node可能关联的 numa 节点或 -1
返回
如果成功则为 true,否则为 false

◆ mi_manage_os_memory_ex()

bool mi_manage_os_memory_ex ( void * start,
size_t size,
bool is_committed,
bool is_large,
bool is_zero,
int numa_node,
bool exclusive,
mi_arena_id_t * arena_id )

将外部分配的内存作为 mimalloc arena 进行管理。

此内存不会被 mimalloc 释放。

参数
start区域的起始地址。
size区域的大小(以字节为单位)。
is_committed内存是否已提交?
is_large它是否由(已固定的)大型操作系统页面组成?
is_zero内存是否已零初始化?
numa_node关联的 NUMA 节点,或 -1 表示没有 NUMA 偏好。
exclusivearena 是否是独占的(只有与该 arena 关联的堆才能在该 arena 中分配)
arena_id新的 arena 标识符。
返回
如果成功则为 true

◆ mi_process_info()

void mi_process_info ( size_t * elapsed_msecs,
size_t * user_msecs,
size_t * system_msecs,
size_t * current_rss,
size_t * peak_rss,
size_t * current_commit,
size_t * peak_commit,
size_t * page_faults )

返回进程信息(时间与内存使用)。

参数
elapsed_msecs可选。进程经过的挂钟时间(毫秒)。
user_msecs可选。用户时间(毫秒)(作为所有线程的总和)。
system_msecs可选。系统时间(毫秒)。
current_rss可选。当前工作集大小(已触及的页面)。
peak_rss可选。峰值工作集大小(已触及的页面)。
current_commit可选。当前已提交内存(由页面文件支持)。
peak_commit可选。峰值已提交内存(由页面文件支持)。
page_faults可选。硬页面错误计数。

current_rss 在 Windows 和 MacOSX 上是精确的;其他系统使用 current_commit 估算此值。commit 在 Windows 上是精确的,但在其他系统上估算为 mimalloc 保留的可读/写内存量。

◆ mi_register_deferred_free()

void mi_register_deferred_free ( mi_deferred_free_fun * deferred_free,
void * arg )

注册延迟释放函数。

参数
deferred_free延迟释放函数的地址,或 NULL 以注销。
arg将传递给延迟释放函数的参数。

一些运行时系统使用延迟释放,例如在使用引用计数来限制最坏情况下的释放时间时。这些系统可以注册(可重入的)延迟释放函数以按需释放更多内存。当 force 参数为 true 时,所有可能的内存都应该被释放。per-thread heartbeat 参数是单调递增的,并且如果程序确定性地分配,则保证是确定性的。deferred_free 函数保证在一定数量的分配后(无论是否释放或可用空闲内存)被确定性地调用。最多只有一个 deferred_free 函数可以处于活动状态。

◆ mi_register_error()

void mi_register_error ( mi_error_fun * errfun,
void * arg )

注册错误回调函数。

参数
errfun发生错误时调用的错误函数(使用 NULL 表示默认)
arg将传递给错误函数的额外参数。

在 mimalloc 中发生错误后(通过输出函数发出错误消息后),将调用 errfun 函数。从 errfun 函数返回始终是合法的,在这种情况下,分配函数通常返回 NULL 或忽略该条件。默认函数仅在安全模式下编译时发生 EFAULT 错误时调用 abort()。可能的错误代码是

  • EAGAIN: 检测到双重释放(仅在调试和安全模式下)。
  • EFAULT: 检测到损坏的空闲列表或元数据(仅在调试和安全模式下)。
  • ENOMEM: 没有足够的内存来满足请求。
  • EOVERFLOW: 请求太大,例如在 mi_calloc() 中,countsize 参数太大。
  • EINVAL: 试图释放或重新分配无效指针。

◆ mi_register_output()

void mi_register_output ( mi_output_fun * out,
void * arg )

注册输出函数。

参数
out输出函数,使用 NULL 输出到 stderr。
arg将传递给输出函数的参数。

调用 out 函数以输出 mimalloc 的任何信息,例如详细或警告消息。

◆ mi_reserve_huge_os_pages_at()

int mi_reserve_huge_os_pages_at ( size_t pages,
int numa_node,
size_t timeout_msecs )

在特定的 numa_node 上保留 pages 个巨大的操作系统页面(1GiB),但最多在 timeout_msecs 毫秒后停止。

参数
pages要保留的 1GiB 页数。
numa_node保留内存的 NUMA 节点(从 0 开始)。使用 -1 表示无亲和性。
timeout_msecs尝试保留的最大毫秒数,或 0 表示无超时。
返回
如果成功则为 0,如果内存不足则为 ENOMEM,如果超时则为 ETIMEDOUT

保留的内存由 mimalloc 用于满足分配。如果估计需要超过 timeout_msecs 的 1.5 倍时间,则可能会在 timeout_msecs 到期之前退出。时间限制是必要的,因为在某些操作系统上,如果物理内存碎片化,保留连续内存可能需要很长时间。

◆ mi_reserve_huge_os_pages_at_ex()

int mi_reserve_huge_os_pages_at_ex ( size_t pages,
int numa_node,
size_t timeout_msecs,
bool exclusive,
mi_arena_id_t * arena_id )

将巨大的操作系统页面(1GiB)保留到单个 arena 中。

参数
pages要保留的 1GiB 页数。
numa_node关联的 NUMA 节点,或 -1 表示没有 NUMA 偏好。
timeout_msecs此操作允许的最大毫秒数。(0 为无限)
exclusive如果独占,则只有与此 arena 关联的堆才能在其中分配。
arena_idarena 标识符。
返回
如果成功则为 0,如果内存不足则为 ENOMEM,如果超时则为 ETIMEDOUT

◆ mi_reserve_huge_os_pages_interleave()

int mi_reserve_huge_os_pages_interleave ( size_t pages,
size_t numa_nodes,
size_t timeout_msecs )

numa_nodes 个节点上平均分配 pages 个巨大的操作系统页面(1GiB),但最多在 timeout_msecs 毫秒后停止。

参数
pages要保留的 1GiB 页数。
numa_nodes要将页面平均分配到的节点数,或 0 表示使用实际的 NUMA 节点数。
timeout_msecs尝试保留的最大毫秒数,或 0 表示无超时。
返回
如果成功则为 0,如果内存不足则为 ENOMEM,如果超时则为 ETIMEDOUT

保留的内存由 mimalloc 用于满足分配。如果估计需要超过 timeout_msecs 的 1.5 倍时间,则可能会在 timeout_msecs 到期之前退出。时间限制是必要的,因为在某些操作系统上,如果物理内存碎片化,保留连续内存可能需要很长时间。

◆ mi_reserve_os_memory()

int mi_reserve_os_memory ( size_t size,
bool commit,
bool allow_large )

为 mimalloc 保留操作系统内存。

在再次从操作系统分配之前使用保留区域。通过预先保留大区域,分配可以更高效,并且可以在没有 mmap/VirtualAlloc 的系统上更好地管理(例如 WASM)。

参数
size要保留的大小。
commit预先提交内存。
allow_large允许使用大型操作系统页面(2MiB)吗?
返回
如果成功则为 0,否则为错误代码(例如 ENOMEM)。

◆ mi_reserve_os_memory_ex()

int mi_reserve_os_memory_ex ( size_t size,
bool commit,
bool allow_large,
bool exclusive,
mi_arena_id_t * arena_id )

保留操作系统内存以在 arena 中管理。

参数
size要保留的大小。
commit内存是否应初始提交?
allow_large允许使用大型操作系统页面吗?
exclusive返回的 arena 是否是独占的?
arena_id新的 arena 标识符。
返回
成功时为零,否则为错误代码。

◆ mi_stats_merge()

void mi_stats_merge ( void )

将线程本地统计信息与主要统计信息合并并重置。

◆ mi_stats_print()

void mi_stats_print ( void * out)

已弃用。

参数
out忽略,默认输出到注册的输出函数或 stderr。

在调试版本中使用时最详细。

◆ mi_stats_print_out()

void mi_stats_print_out ( mi_output_fun * out,
void * arg )

打印主要统计信息。

参数
out输出函数,或 NULL 表示默认。
arg传递给 out 的可选参数(如果不是 NULL

在调试版本中使用时最详细。

◆ mi_stats_reset()

void mi_stats_reset ( void )

重置统计信息。

◆ mi_subproc_add_current_thread()

void mi_subproc_add_current_thread ( mi_subproc_id_t subproc)

将当前线程添加到给定的子进程。

这应该在线程创建后(且尚未进行任何分配)立即调用

◆ mi_subproc_delete()

void mi_subproc_delete ( mi_subproc_id_t subproc)

删除之前创建的子进程。

参数
subproc子进程标识符。只有在所有关联线程都已终止时才删除子进程。

◆ mi_subproc_main()

mi_subproc_id_t mi_subproc_main ( void )

获取主子进程标识符。

◆ mi_subproc_new()

mi_subproc_id_t mi_subproc_new ( void )

创建一个新的子进程(尚未关联任何线程)。

返回
新的子进程标识符。

◆ mi_thread_done()

void mi_thread_done ( void )

在线程上取消初始化 mimalloc。

不应使用,因为在大多数系统(pthreads、windows)上这是自动完成的。确保尚未释放的任何内存(但将来将由其他线程释放)得到正确处理。

◆ mi_thread_init()

void mi_thread_init ( void )

在线程上初始化 mimalloc。

不应使用,因为在大多数系统(pthreads、windows)上这是自动完成的。

◆ mi_thread_stats_print_out()

void mi_thread_stats_print_out ( mi_output_fun * out,
void * arg )

打印此线程的堆统计信息。

参数
out输出函数,或 NULL 表示默认。
arg传递给 out 的可选参数(如果不是 NULL

在调试版本中使用时最详细。

◆ mi_usable_size()

size_t mi_usable_size ( void * p)

返回内存块中可用的字节数。

参数
p指向先前分配的内存的指针(或 NULL
返回
返回内存块中可用的字节数,如果 pNULL 则返回 0。

返回的大小可用于成功调用 mi_expand。返回的大小始终至少等于 p 的已分配大小。

另请参见
_msize (Windows)
malloc_usable_size (Linux)
mi_good_size()

◆ mi_zalloc_small()

void * mi_zalloc_small ( size_t size)

分配一个零初始化的小型对象。

参数
size大小(以字节为单位),最多可为 MI_SMALL_SIZE_MAX
返回
指向至少 size 字节的新分配的零初始化内存的指针,如果内存不足则为 NULL。此函数旨在用于运行时系统以获得最佳性能,并且不检查 size 是否确实很小 - 请谨慎使用!