You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 12:12:03