【Wins】Visual Studio memory leak check使用教程

cpp 复制代码
.\_build\_deploy\bin\example_euroc_old.exe "C:\ws\polaries\demo\SLAMConfig.json" "C:\data\hulk_#3\SLAMCalibration.json" "C:\data\hulk_#3\data\hulk_3_test_3\" "C:\data\hulk_#3\data\hulk_3_test_3\timestamp.txt"
cpp 复制代码
        if( i % 100 == 0){
            std::cout << "Processing frame: " << i << std::endl;
            std::cin.get();
        }


搜索找到对应的执行程序

选中点击 attach

进入检测运行的程序界面如下

snapshoot 使能

获取当前内存中的堆管理数据,点击后获取第一次快照

回到这个程序执行界面

点击任意按键程序继续运行,这个时候开始第二次运行的 堆栈的积累

如下程序运行到 100 次之后再一次暂停,如果由内存泄漏,堆栈会有增加如下

重复上面的操作

多次 执行上面的操作循环

如上,多次操作分析对应的堆栈,给出分析结果。

怎么使用这个文件?

你提供了 三次不同时间点的 Visual Studio 内存诊断快照(Snapshot) ,我们可以用这些 View Heap 数据 来对比堆内存变化,定位内存泄漏的位置 ,并指导你如何 找到对应代码


✅ 一、三次快照关键数据对比(从图中提取)

我们以 第5个快照(时间为 268.15s) 为例,三次运行的堆内存数据如下:

运行次数 时间 总分配次数 堆大小(KB) 备注
第1次 268.15s 1,042,374 103,297.91 KB 基准
第2次 268.15s 1,042,374 103,297.91 KB 相同
第3次 268.15s 1,042,374 103,297.91 KB 相同

📌 结论

  • 三次运行的 内存增长完全一致
  • 说明泄漏是 稳定复现的,不是随机行为。
  • 你可以 稳定地调试和分析泄漏点

✅ 二、内存增长过程(以第一次为例)

快照 时间 分配次数 堆大小(KB) 每次增量(KB)
#1 6.83s 40 21.60 KB ---
#2 31.99s 249,598 56,558.35 KB +56,536 KB
#3 65.34s 473,960 69,778.50 KB +13,220 KB
#4 100.33s 701,265 76,144.98 KB +6,366 KB
#5 268.15s 1,042,374 103,297.91 KB +27,152 KB

📈 趋势分析

  • 初期 爆发式分配(可能是初始化)。
  • 后期 持续增长无释放迹象
  • 典型的内存泄漏模式

✅ 三、如何找到泄漏的代码位置?

🔍 步骤 1:在 Visual Studio 中打开 View Heap

  1. 快照 #5(268.15s) 上点击 "View Heap"
  2. 会打开一个窗口,显示 所有堆上的对象类型它们的大小/数量

🔍 步骤 2:找增长最多的对象类型

在 View Heap 中,按 "Size" 或 "Count" 排序,找出:

  • 哪些对象类型持续增长 (比如 std::unordered_map<MyClass>
  • 哪些对象数量每次快照都在增加

📌 重点看

  • 自定义类(比如 Landmark, Frame, MapPoint
  • STL 容器(比如 std::vector, std::shared_ptr<MyClass>

🔍 步骤 3:查看分配调用栈(Allocation Call Stack)

在 View Heap 中:

  • 选中一个 增长明显的对象类型
  • 点击 "View Call Stack""Allocation Stack"
  • 会显示 是哪个函数在一直分配它

📌 你之前提供的调用栈示例

复制代码
slam_core_engine.dll!UpdaterLAMdelayed_init(...)
slam_core_engine.dll!VioManager::frame_bundle_handler(...)

→ 说明每次帧处理都会调用这个函数,持续插入对象到 map 中 ,但 不清理


✅ 四、总结:你怎么找到泄漏的代码

步骤 操作 目的
1 点击快照 → View Heap 看哪些对象在增长
2 排序 by Size / Count 找出增长最多的类型
3 选中对象 → View Call Stack 看是哪个函数在分配
4 打开源码 → 检查是否只 insert 不 erase 找到泄漏逻辑
5 检查 shared_ptr 是否循环引用 避免智能指针互相持有

✅ 五、总结一句话

你在 View Heap 里要找到"持续增长"的对象类型,然后看它的分配调用栈,就能定位到是哪个函数在持续分配但不释放------这就是内存泄漏的代码位置。


如果你能把你 View Heap 里的对象类型列表 贴出来(比如 std::unordered_map<unsigned int, std::shared_ptr<Landmark>> 这种),我可以帮你 精确定位是哪一行代码泄漏 ,并给出 修复建议

下面是第二阶段对比操作流程细节:

下面给出在 Visual Studio 2022把两个内存快照拿出来对比 的完整路径,一步一步截图式指引,你照着点即可。


✅ 1. 确保正在调试

  • 必须以 "Debug" 模式启动(F5)。
  • 启动后,Diagnostic Tools 窗口会自动弹出。
    若没看到:
    菜单栏 → Debug → Windows → Show Diagnostic Tools(Ctrl + Alt + F2)

✅ 2. 切到 Memory Usage 页签

  • 在 Diagnostic Tools 窗口顶部 有一排小页签
    CPU Usage | Memory Usage | Events
    → 点 Memory Usage

✅ 3. 找到 Snapshots 表格

  • 同窗口下半区 有一个 "Snapshots" 列表(时间轴下方)。
    每一行就是一次快照,列头为
    Time | Allocations (Diff) | Heap Size (Diff)

✅ 4. 拍快照(如果还没拍)

  • 调试过程中,随时点 "Take Snapshot" 按钮(左上角小相机图标)。
    拍完后,该行会出现在 Snapshots 列表里。

✅ 5. 选中两个快照

  • 按住 Ctrl → 左击两行(例如 #2 和 #5)。
    两行同时高亮即可。

✅ 6. 对比快照

  • 有两种方式启动对比:
    1. 右键 → Compare Snapshots
    2. 列表上方工具栏 "Compare Snapshots" 按钮(两个圆圈图标)

✅ 7. 看差异结果

  • VS 会弹出 新标签页 Snapshot Diff #2 vs #5
    里面列出 增长/减少的对象类型 ,按 Size Diff 排序即可一眼看出谁涨了几十 MB

✅ 8. 定位代码

  • 在差异表里 双击某个类型 → 打开 Allocation View
  • 再点 "View Call Stack" (或右侧小栈图标),就能看到 哪一行 operator new 一直被执行

✅ 9. 回到源码

  • 调用栈最顶层是你自己的函数,双击该行 → 直接跳到 .cpp 的对应行。
    接下来你就检查是不是 insert/newerase/delete 即可。

🔍 一张图总结(VS2022 界面)

复制代码
┌─ Diagnostic Tools ─────────────────────────────┐
│ [CPU Usage] [Memory Usage] [Events]            │← 2. 点 Memory Usage
│                                                 │
│  Time轴                                         │
│  │     ●───●────●───●─────●──►               │
│                                                 │
│  Snapshots                                      │
│  □ Time  Allocations(Diff)  Heap Size(Diff)    │← 3. 快照列表
│  #1 6.83s   40             21.60 KB            │
│  #2 ...    +249 558        +56 536 KB          │
│  #5 ...   +1 042 374       +103 297 KB         │← 5. Ctrl 选中两行
│                                                 │
│  [← Take Snapshot] [Compare Snapshots]         │← 6. 右键或按钮对比
└─────────────────────────────────────────────────┘

照这个流程,30 秒就能把泄漏对象、调用栈、源码行号全挖出来

如果你在哪个小环节没看到按钮或列表,直接截图给我,我帮你圈出来。

你现在已经走到 VS2022 的"对比快照"界面 了!

截图里能看到:

  • 左上角提示:
    "Compare With Baseline: Snapshot #4"
    → 说明你正在用 Snapshot #4(100.33 s)作为基准,与其他快照对比。
  • 下方表格:
    Object Type | Count Diff | Size Diff (Bytes)
    → 这就是 "谁涨了、涨了多少" 的差异表。

✅ 下一步:定位泄漏对象 & 代码

① 先确认对比的是哪两个快照

当前视图是把 #4 当作 baseline ,对比的是 #5(268.15 s)

(因为 #5 是最新一次,Time=268.15 s 那行高亮)。

如果你想换别的 baseline,只需:

  • Snapshots 列表里右键任意一行 → Set as Baseline
    再点 View Diff 即可。
② 看差异表(已经在你图上)
Object Type Count Diff Size Diff
void +1,187 +73,487 B

这只是 系统未解析的块 (俗称"匿名分配"),还没展开 具体 C++ 类型
→ 需要把"未解析"展开成真实类型。

③ 取消"隐藏未解析分配"

在差异表上方有一条复选框:
☐ Hide Unresolved Allocations

→ 把它 取消勾选

立刻会出现 具体的 C++ 类名 / STL 容器名 ,例如
std::unordered_map<unsigned int,std::shared_ptr<Landmark>>
std::vector<CVHelper::Image>

等等。

④ 按 Size Diff 排序

Size Diff (Bytes) 列头,从大到小排

增长最多的类型排在第一行,它就是泄漏主角

⑤ 看调用栈
  • 双击 那一行(或右键 → View Call Stack)
    → 弹出 Allocation Stack ,里面逐层显示:

    复制代码
    slam_core_engine.dll!operator new
    slam_core_engine.dll!VioManager::frame_bundle_handler
    example_euroc_old.exe!main
  • 双击最顶层你熟悉的函数 ,VS 会跳到 .cpp 源文件对应行


✅ 一张图总结你当前该点的按钮

复制代码
┌─ Diagnostic Tools ─────────────────────────────┐
│  Compare With Baseline: Snapshot #4            │← 确认 baseline
│                                                │
│  ☑ Hide Unresolved Allocations   ←取消勾选!   │
│                                                │
│  Object Type  Count Diff  Size Diff (Bytes)    │
│  void         +1 187      +73 487             │← 取消勾选后这里
│  ........                                     │   会变成具体类名
│                                                │
│  [View Diff] [View Call Stack]                │← 双击行或点这里
└────────────────────────────────────────────────┘

✅ 30 秒操作清单

  1. 取消勾选 Hide Unresolved Allocations
  2. 按 Size Diff 从大到小排序
  3. 双击增长最多的那一行
  4. 在弹出窗口点 View Call Stack
  5. 双击栈里最顶层自己的函数 → 源码行现身

做完这 5 步,泄漏代码行就摆在面前了

相关推荐
每天更新5 小时前
VSCODE 使用GDB
ide·vscode·编辑器
星夜钢琴手5 小时前
推荐的 Visual Studio 2026 Insider C++ 程序项目属性配置
c++·visual studio
paoqi 包奇6 小时前
pycharm中使用anaconda指定虚拟环境
ide·python·pycharm
傅科摆 _ py7 小时前
解决 Vscode 中运行键突然消失的问题
ide·vscode·编辑器
丨Sky丨夜吻7 小时前
vscode扩展
ide·vue.js·vscode
慕伏白8 小时前
【慕伏白】Android Studio 无线调试配置
android·ide·android studio
yeziyfx13 小时前
Android Studio制作.9图(点9图/9Patch图)
android·ide·android studio
小蕾Java1 天前
PyCharm 2025:使用图文教程!
ide·python·pycharm
刘登辉1 天前
idea使用联网缓存的pom进行离线开发
java·ide·intellij-idea·离线开发