Chapter 22 Memory profiling with Spacetime
1 Overview
Spacetime is the name given to functionality within the OCaml compiler that provides for accurate profiling of the memory behaviour of a program. Using Spacetime it is possible to determine the source of memory leaks and excess memory allocation quickly and easily. Excess allocation slows programs down both by imposing a higher load on the garbage collector and reducing the cache locality of the program’s code. Spacetime provides full backtraces for every allocation that occurred on the OCaml heap during the lifetime of the program including those in C stubs.
Spacetime only analyses the memory behaviour of a program with respect to the OCaml heap allocators and garbage collector. It does not analyse allocation on the C heap. Spacetime does not affect the memory behaviour of a program being profiled with the exception of any change caused by the overhead of profiling (see section 22.3)—for example the program running slower might cause it to allocate less memory in total.
Spacetime is currently only available for x86-64 targets and has only been tested on Linux systems (although it is expected to work on most modern Unix-like systems and provision has been made for running under Windows). It is expected that the set of supported platforms will be extended in the future.
2 How to use it
2.1 Building
To use Spacetime it is necessary to use an OCaml compiler that was configured with the -spacetime option. It is not possible to select Spacetime on a per-source-file basis or for a subset of files in a project; all files involved in the executable being profiled must be built with the Spacetime compiler. Only native code compilation is supported (not bytecode).
If the libunwind library is not available on the system then it will not be possible for Spacetime to profile allocations occurring within C stubs. If the libunwind library is available but in an unusual location then that location may be specified to the configure script using the -libunwinddir option (or alternatively, using separate -libunwindinclude and -libunwindlib options).
OPAM switches will be provided for Spacetime-configured compilers.
Once the appropriate compiler has been selected the program should be built as normal (ensuring that all files are built with the Spacetime compiler—there is currently no protection to ensure this is the case, but it is essential). For many uses it will not be necessary to change the code of the program to use the profiler.
Spacetime-configured compilers run slower and occupy more memory than their counterparts. It is hoped this will be fixed in the future as part of improved cross compilation support.
2.2 Running
Programs built with Spacetime instrumentation have a dependency on the libunwind library unless that was unavailable at configure time or the -disable-libunwind option was specified (see section 22.3).
Setting the OCAML_SPACETIME_INTERVAL environment variable to an integer representing a number of milliseconds before running a program built with Spacetime will cause memory profiling to be in operation when the program is started. The contents of the OCaml heap will be sampled each time the number of milliseconds that the program has spent executing since the last sample exceeds the given number. (Note that the time base is combined user plus system time—not wall clock time. This peculiarity may be changed in future.)
The program being profiled must exit normally or be caused to exit using the SIGINT signal (e.g. by pressing Ctrl+C). When the program exits files will be written in the directory that was the working directory when the program was started. One Spacetime file will be written for each process that was involved, indexed by process ID; there will normally only be one such. The Spacetime files may be substantial. The directory to which they are written may be overridden by setting the OCAML_SPACETIME_SNAPSHOT_DIR environment variable before the program is started.
Instead of using the automatic snapshot facility described above it is also possible to manually control Spacetime profiling. (The environment variables OCAML_SPACETIME_INTERVAL and OCAML_SPACETIME_SNAPSHOT_DIR are then not relevant.) Full documentation as regards this method of profiling is provided in the standard library documentation (section 25) for the Spacetime module.
2.3 Analysis
The compiler distribution does not itself provide the facility for analysing Spacetime output files; this is left to external tools. The first such tool will appear in OPAM as a package called prof_spacetime. That tool will provide interactive graphical and terminal-based visualisation of the results of profiling.
3 Runtime overhead
The runtime overhead imposed by Spacetime varies considerably depending on the particular program being profiled. The overhead may be as low as ten percent—but more usually programs should be expected to run at perhaps a third or quarter of their normal speed. It is expected that this overhead will be reduced in future versions of the compiler.
Execution speed of instrumented programs may be increased by using a compiler configured with the -disable-libunwind option. This prevents collection of profiling information from C stubs.
Programs running with Spacetime instrumentation consume significantly more memory than their non-instrumented counterparts. It is expected that this memory overhead will also be reduced in the future.
4 For developers
The compiler distribution provides an “otherlibs” library called raw_spacetime_lib for decoding Spacetime files. This library provides facilities to read not only memory profiling information but also the full dynamic call graph of the profiled program which is written into Spacetime output files.
A library package spacetime_lib will be provided in OPAM to provide an interface for decoding profiling information at a higher level than that provided by raw_spacetime_lib.