如何通过DPDK rte_malloc相关API追踪内存分配,按type统计大页使用
核心问题说明
你遇到的是DPDK已知的文档和实现不一致的问题:rte_malloc_dump_stats的按type统计功能仅在文档中描述,实际主线版本中heap_alloc函数的type参数被标记为__rte_unused,没有任何统计逻辑用到该参数,所以原生无法实现按type查询内存占用的能力。
可用的大页内存追踪API
DPDK现有原生接口可以满足不同维度的大页内存监控需求:
rte_malloc_get_stats():可以获取整个DPDK内存堆的全局统计数据,包括总分配字节数、总释放字节数、当前已分配字节数、最大连续空闲块等基础指标,适合全局大页水位监控。rte_malloc_heap_get_stats():支持按NUMA节点对应的独立内存堆获取统计数据,适合需要区分不同NUMA节点内存占用的场景。- 内存调试编译选项:开启
CONFIG_RTE_MALLOC_DEBUG编译选项后,可以开启内存越界检测、泄漏检测能力,结合调试工具可以定位具体内存块的分配信息,但默认不开启,会带来一定性能损耗。 - 分配/释放钩子接口:DPDK的malloc层支持注册自定义的分配、释放钩子函数,可以在分配和释放动作触发时拿到type、大小等全部参数,是自定义统计的核心实现基础。
按type统计的补丁情况
目前DPDK主线没有合入实现type统计的官方补丁,该type参数从18.11版本开始就处于预留未使用的状态,仅社区存在零散的第三方个人实现补丁,未进入正式版本。
本场景下堆内存追踪实现方案
推荐使用自定义malloc钩子的方式实现,对现有业务代码侵入性极低,完全可以实现你预期的按type统计功能,示例实现逻辑如下:
#include <rte_malloc.h> #include <rte_hash.h> /* 单type统计结构 */ struct type_stats { uint64_t alloc_bytes; uint32_t alloc_cnt; }; static struct rte_hash *type_stats_hash; /* 分配动作钩子 */ static void malloc_hook_alloc(const void *ptr, size_t size, const char *type, int socket) { struct type_stats *stats; int ret = rte_hash_lookup_data(type_stats_hash, type, (void **)&stats); if (ret < 0) { /* 新增未记录的type统计项 */ stats = rte_zmalloc(NULL, sizeof(struct type_stats), 0); rte_hash_add_key_data(type_stats_hash, type, stats); } __atomic_add_fetch(&stats->alloc_bytes, size, __ATOMIC_RELAXED); __atomic_add_fetch(&stats->alloc_cnt, 1, __ATOMIC_RELAXED); } /* 释放动作钩子 */ static void malloc_hook_free(const void *ptr, size_t size, const char *type, int socket) { struct type_stats *stats; int ret = rte_hash_lookup_data(type_stats_hash, type, (void **)&stats); if (ret == 0) { __atomic_sub_fetch(&stats->alloc_bytes, size, __ATOMIC_RELAXED); __atomic_sub_fetch(&stats->alloc_cnt, 1, __ATOMIC_RELAXED); } } /* 统计模块初始化,在rte_eal_init之后调用即可 */ void malloc_type_stats_init(void) { struct rte_hash_parameters hash_params = { .name = "type_stats_hash", .entries = 1024, /* 可根据实际用到的type数量调整 */ .key_len = RTE_MALLOC_TYPE_LEN_MAX, .socket_id = SOCKET_ID_ANY, }; type_stats_hash = rte_hash_create(&hash_params); /* 注册钩子 */ rte_malloc_hook_register_alloc(malloc_hook_alloc); rte_malloc_hook_register_free(malloc_hook_free); } /* 自定义按type导出统计的接口 */ void dump_type_stats(const char *type) { struct type_stats *stats; int ret = rte_hash_lookup_data(type_stats_hash, type, (void **)&stats); if (ret == 0) { printf("type: %s, 已分配字节数: %lu, 活跃分配次数: %u\n", type, stats->alloc_bytes, stats->alloc_cnt); } else { printf("无对应type的统计数据: %s\n", type); } }
完成初始化后,直接调用dump_type_stats("objecttype-1")即可获取对应type的内存占用统计。
内容的提问来源于stack exchange,提问作者jk100
相关产品推荐
相关产品推荐

