目 录CONTENT

文章目录

内存分析工具 Valgrind(massif)

TalentQ
2025-08-28 / 0 评论 / 0 点赞 / 2 阅读 / 0 字

1 介绍

Massif是一个堆分析器,能够测量程序使用了多少堆内存。

Massif将程序堆的快照保存起来(生成massif.out文件),然后使用Massif-Visualizer进行可视化分析。

2 安装

sudo apt install massif-visualizer

3 Valgrind massif 使用方法

参数示例:

valgrind -v --tool=massif \
         --time-unit=B \
         --detailed-freq=1 \
         --massif-out-file=/path_to/massif.out \
         ./(path to)/test-demo <+ arg1 arg2 ... argn>

参数解释:

  • -v:启用详细输出模式

  • --tool:指定使用massif工具

  • --time-uint:设置时间单位为Bytes

  • --detailed-freq:设置详细快照的频率为1,意味着每次内存分配都会生成详细的快照

  • --massif-out-file:设置输出文件的名称

  • ./(path to)/test-demo:要分析的目标程序

可视化工具:

massif-visualizer /path_to/massif.out

4 使用示例

测试代码:

#include <stdlib.h>

/**
 * 分配指定字节数的内存块
 * @param size 需要分配的字节数
 * @return 成功时返回指向分配内存的指针;失败时返回 NULL
 */
void* create(unsigned int size) {
    return malloc(size);
}

/**
 * 分配并立即释放一块内存
 * 用于演示“分配即释放”的场景,但注意:create() 返回的指针未被使用,
 * 如果 create() 内部有额外资源初始化,则可能造成资源泄漏。
 * @param size 需要分配并释放的字节数
 */
void create_destory(unsigned int size) {
    void* p = create(size); // 分配内存
    free(p);                // 立即释放
}

int main(void) {
    const int loop = 4;           // 循环次数
    char* a[loop];                // 用于保存 malloc 得到的指针,以便后续统一释放
    unsigned int kilo = 1024;     // 1 KB = 1024 字节

    /* ----------- 第一阶段:循环分配内存 ----------- */
    for (int i = 0; i < loop; i++) {
        /* 1. 调用自定义 create() 分配 10 KB,但返回值被丢弃,造成内存泄漏 */
        const unsigned int create_size = 10 * kilo;
        create(create_size);  // 内存泄漏:未保存指针,后续无法 free

        /* 2. 使用标准 malloc 再分配 10 KB,并把地址保存到数组 a[i] */
        const unsigned int malloc_size = 10 * kilo;
        a[i] = malloc(malloc_size);

        /* 3. 调用 create_destory():内部先 create 100 KB,再立即 free */
        const unsigned int create_destory_size = 100 * kilo;
        create_destory(create_destory_size);
    }

    /* ----------- 第二阶段:释放 malloc 得到的内存 ----------- */
    for (int i = 0; i < loop; i++) {
        free(a[i]);  // 释放第一阶段 malloc 得到的内存
    }

    /* 注意:第一阶段 create() 分配的内存未释放,造成内存泄漏 */
    return 0;
}

编译指令:

gcc -g test-demo.c -o test-demo

检测程序:

valgrind -v --tool=massif --time-unit=B --detailed-freq=1 --massif-out-file=massif.out ./test-demo

可视化:

massif-visualizer ./massif.out

随着对内存分配的推进,可以清晰地看到任意时候的未释放的堆内存大小。到最后还有40kB,说明程序结束时,有40kB的内存没有被正常释放,也就意味着发生了内存泄露。

0

评论区