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
相关产品推荐
相关产品推荐

