Skip to content

ANDRVV/zprof

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

61 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation



Zprof



The Zprof cross-allocator profiler

Zprof is a cross-allocator wrapper for profiling memory data.

Developed for use in Debug or official modes, it guarantees nearly the same performance as the wrapped allocator. Zprof's development is based on a primary priority: ease of use, improved efficiency, readability, clean, minimal, and well-documented code.

๐Ÿ“– Table of Contents

๐Ÿ“ฅ Installation

Using a package manager

Add Zprof to your project's build.zig.zon:

.{
    .name = "my-project",
    .version = "1.2.0",
    .dependencies = .{
        .zprof = .{
            .url = "https://github.com/ANDRVV/zprof/archive/v1.2.0.zip",
            .hash = "...",
        },
    },
}

Then in your build.zig, add:

// Add Zprof as a dependency
const zprof_dep = b.dependency("zprof", .{
        .target = target,
        .optimize = optimize,
});

// Add the module to your executable
exe.root_module.addImport("zprof", zprof_dep.module("zprof"));

Else can you you put zprof.zig in yours project path and import it.

๐Ÿš€ Quick Start

Here's how to use Zprof in three easy steps:

const std = @import("std");
const Zprof = @import("zprof").Zprof;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    var gpa_allocator = gpa.allocator();
    
    // 1. Create a profiler by wrapping your allocator
    var zprof = try Zprof(false).init(&gpa_allocator, true);
    // false disable thread-safe mode and true enables logging

    defer zprof.deinit(); // deallocates Zprof instance
    
    // 2. Use the profiler's allocator instead of your original one
    const allocator = zprof.allocator;
    
    // 3. Use the allocator as normal
    const data = try allocator.alloc(u8, 1024);
    defer allocator.free(data);
    
    // Check for leaks
    std.debug.print("Has leaks: {}\n", .{zprof.profiler.hasLeaks()});
}

๐Ÿ” Usage

Basic Usage

To start profiling memory usage, simply wrap your allocator with Zprof:

var zprof = try Zprof(false).init(&allocator, false); // on init, false disables automatic logging
const tracked_allocator = zprof.allocator;

Thread safe mode

To use Zprof with mutex, you must enable thread-safe mode:

var zprof = try Zprof(true).init(&allocator, false); // true enables thread-safe mode
const tracked_allocator = zprof.allocator;

Logging

If logging is enabled, logs allocated/deallocated bytes when allocator allocates or deallocates.

var zprof = try Zprof(false).init(&allocator, true); // true enables automatic logging
const tracked_allocator = zprof.allocator;

const data = try allocator.alloc(u8, 1024); // prints: Zprof::ALLOC allocated=1024
allocator.free(data); // prints: Zprof::FREE deallocated=1024

Detecting Memory Leaks

Zprof makes it easy to detect memory leaks in your application:

// At the end of your program or test
const has_leaks = zprof.profiler.hasLeaks();
if (has_leaks) {
    // Handle leaks (e.g., report, abort in tests)
    std.debug.print("Memory leak detected!\n", .{});
    return error.MemoryLeak;
}

Full Profiler API

The Profiler struct contains several fields and methods:

Fields

Field Type Description
allocated u64 Total bytes allocated since initialization
alloc_count u64 Number of allocation operations
free_count u64 Number of deallocation operations
live_peak u64 Maximum memory usage at any point
live_bytes u64 Current memory usage

Methods

Method Description
hasLeaks() Returns true if there are memory leaks
reset() Resets all profiling statistics

๐Ÿ“ Examples

Testing for Memory Leaks

test "no memory leaks" {
    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
    defer arena.deinit();
    var arena_allocator = arena.allocator();
    
    var zprof = try Zprof(false).init(&arena_allocator, false);
    defer zprof.deinit();

    const allocator = zprof.allocator;
    
    // Perform allocations
    const data = try allocator.alloc(u8, 1024);
    defer allocator.free(data);
    
    // Verify no leaks
    try std.testing.expect(!zprof.profiler.hasLeaks());
}

Made with โค๏ธ for the Zig community

Copyright (c) 2025 Andrea Vaccaro

About

๐Ÿงฎ Cross-allocator profiler for Zig

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Contributors 3

  •  
  •  
  •  

Languages