# Fil Memory Profile

## Sat Mar 15 21:22:48 2025

## Command

`./pyperplan.py -H hff -s bfs ../../benchmarks/ipc2023-learning/testing/sokoban/easy-p16.pddl`

## Profiling result

·

> ### Find performance bottlenecks in your data processing jobs with the Sciagraph profiler

> The Sciagraph profiler can help you find performance and memory bottlenecks with low overhead, so you can use it in both development and production.

> Unlike Fil, it includes performance profiling. Sciagraph's memory profiling uses sampling so it runs faster than Fil, but unlike Fil it can't accurately profile small allocations or run natively on macOS.

·

> Need help, or does something look wrong? Read the documentation, and if that doesn't help please file an issue and I'll try to help.

## Learn how to reduce memory usage

Need help reducing your data processing application's memory use? Check out tips and tricks here.

## Understanding the graphs

The flame graphs shows the callstacks responsible for allocations at peak.

The wider (and the redder) the bar, the more memory was allocated by that function or its callers. If the bar is 100% of width, that's all the allocated memory.

The left-right axis has no meaning! The order of frames is somewhat arbitrary, for example beause multiple calls to the same function may well have been merged into a single callstack. So you can't tell from the graph which allocations happened first. All you're getting is that at peak allocation these time, these stacktraces were responsible for these allocations.

The first graph shows the normal callgraph: if `main()` calls `g()` calls `f()`, let's say, then `main()` will be at the top. The second graph shows the reverse callgraph, from `f()` upwards.

Why is the second graph useful? If `f()` is called from multiple places, in the first graph it will show up multiple times, at the bottom. In the second reversed graph all calls to `f()` will be merged together.

## Understanding what Fil tracks

Fil measures how much memory has been allocated; this is not the same as how much memory the process is actively using, nor is it the same as memory resident in RAM.

- If the data gets dumped from RAM to swap, Fil still counts it but it's not counted as resident in RAM.
- If the memory is a large chunk of all zeros, on Linux no RAM is used by OS until you actually modify that memory, but Fil will still count it.
- If you have memory that only gets freed on garbage collection (this will happen if you have circular references in your data structures), memory can be freed at inconsistent times across different runs, especially if you're using threads.

See this article for more details.