A streaming client for OCaml's Memprof, which generates compact traces
of a program's memory use. The trace is transferred via TCP.
To profile the memory use of a unikernel, there are two options. Either the
unikernel establishes a TCP connection to a listener which dumps the trace into
a file, or the unikernel offers a service where upon connection of a client,
the trace is dumped to.
As preparation in both cases, you need to install this package by executing
opam install memtrace-mirage and add
~packages:[ package "memtrace-mirage" ]
config.ml where you call
From the start: establish a client connection from the unikernel
To trace the entire lifetime of the unikernel, create a client connection at
startup where the trace is dumped to disk:
nc -l 1234 > my-unikernel.trace to dump the trace into a file before
starting the unikernel.
unikernel.ml, add the following code to the
module Memtrace = Memtrace.Make(Pclock)(S.TCP) let start () s = (S.TCP.create_connection (S.tcp s) (Ipaddr.of_string_exn "10.0.0.1", 1234) >|= function | Ok flow -> ignore (Memtrace.start_tracing ~context:None ~sampling_rate:1e-4 flow) | Error e -> Logs.warn (fun m -> m "couldn't connect to tracing sink %a" S.TCP.pp_error e)) >>= fun () -> ... rest of start ...
The unikernel provides a service for a single client
As soon as a client connects, tracing is started. The tracing is only stopped
when the client disconnects. Only a single client is permitted.
First start the unikernel, then execute
nc 10.0.0.2 1234 > my-unikernel.trace.
nc process once you like to stop tracing.
unikernel.ml, add the following code:
module Memtrace = Memtrace.Make(Pclock)(S.TCP) let start () s = S.TCP.listen (S.tcp s) ~port:1234 (fun f -> (* only allow a single tracing client *) match Memtrace.Memprof_tracer.active_tracer () with | Some _ -> Logs.warn (fun m -> m "tracing already active"); S.TCP.close f | None -> Logs.info (fun m -> m "starting tracing"); let tracer = Memtrace.start_tracing ~context:None ~sampling_rate:1e-4 f in Lwt.async (fun () -> S.TCP.read f >|= fun _ -> Logs.warn (fun m -> m "tracing read returned, closing"); Memtrace.stop_tracing tracer); Lwt.return_unit); ... rest of start ...
Trace file analysis
The resulting trace files can be analysed with some simple command-line tools
memtrace opam package, but the recommended interface is the memtrace
viewer, which lives at:
This repository code is based on