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

Zig分配器无需手动释放?未调用dealloc却无内存泄漏疑问

问题:Zig中未调用dealloc却无内存泄漏?

我使用Zig已有数日,正在学习allocator相关知识。据我所知Zig没有垃圾回收机制,因此我认为如下代码会引发内存泄漏问题:

const std = @import("std");
const alloc_1 = std.heap.page_allocator;

pub fn main () !void {
    const arr = try alloc_1.alloc(u8, 3);
    arr[0] = 0;
}

我使用valgrind命令 valgrind --leak-check=full --track-origins=yes ./allocators 检测内存泄漏,得到如下结果:

==23890== Memcheck, a memory error detector
==23890== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==23890== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==23890== Command: ./allocators
==23890== 
==23890== 
==23890== HEAP SUMMARY:
==23890==     in use at exit: 0 bytes in 0 blocks
==23890==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==23890== 
==23890== All heap blocks were freed -- no leaks are possible
==23890== 
==23890== For lists of detected and suppressed errors, rerun with: -s
==23890== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

结果显示所有堆内存都已释放,无泄漏可能,这让我疑惑:为何未调用dealloc,内存却被自动清理了?


解答

原因很简单:进程退出时操作系统会自动回收该进程占用的所有内存资源。

你使用的std.heap.page_allocator底层依赖系统调用(类Unix系统下是mmap)分配整页内存,当程序运行结束后,操作系统会将该进程占用的所有内存(包括通过这类系统调用分配的内存)全部回收,因此Valgrind检测不到内存泄漏。

需要明确几个关键点:

  • 这种“无泄漏”仅针对短生命周期的程序,要是换成长时间运行的服务类程序,不调用dealloc会导致内存持续占用,最终引发真正的内存泄漏。
  • 若使用Zig的其他Allocator(比如std.heap.GeneralPurposeAllocator),开启泄漏检测后,即便操作系统最终会回收内存,程序退出时也会主动报告内存泄漏。示例代码如下:
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const alloc = gpa.allocator();

    const arr = try alloc.alloc(u8, 3);
    arr[0] = 0;
    // 未调用alloc.free(arr)
}

运行后控制台会输出类似内存泄漏的提示信息。


内容的提问来源于stack exchange,提问作者Mr.Barbo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:26:26