This module defines the functions that access heap profiles both during and after execution.
- readProfile :: FilePath -> IO (Maybe Profile)
- type LoadProgress = IO (Either Double Profile)
- type ProfilingStop = IO ()
- readProfileAsync :: FilePath -> IO (LoadProgress, ProfilingStop)
- type ProfileReader = IO Profile
- data ProfilingType loc rem
- type ProfilingCommand = ProfilingType CreateProcess String
- type ProfilingInfo = ProfilingType ProcessHandle Handle
- profile :: ProfilingCommand -> IO (Maybe (ProfileReader, ProfilingStop, ProfilingInfo))
- profileCallback :: ProfilingCommand -> ProfileSink -> IO (Maybe (ProfilingStop, ProfilingInfo))
Reading archived profiles
The simplest case to handle is the traditional method of taking
the profiler output of an earlier run and turning it into an easy to
query structure. This is done by passing
readProfile the log created
by the heap profiler (a file with .hp extension).
If we want to observe the progress of loading, we can perform the
operation asynchronously. We need a query operation to check the
progress and extract the final result after the whole profile was
LoadProgress computation tells us precisely that,
representing progress with a number between 0 and 1.
A common stopping action that can be used to cancel asynchronous loading as well as killing the reading thread during live profiling without touching the slave process.
Read a heap profile asynchronously. Since we might want to interrupt the loading process if it proves to be too long, a stopper action is also returned along with the progress query action. If the stopper action is executed, the query function will return an empty profile as a result.
Profiling running applications
Since we want to possibly look at heap profiles during the run, we might need an action that returns the data recorded so far.
There are two basic ways of profiling: local and remote. Local profiling means that we directly manage the process we are monitoring. In the case of remote profiling we connect to a server that streams profiling information and acts as a proxy between the process to profile and our program. The type of profiling also determines the kind of information available to us after initiating the process, so we need generic labels to distinguish the alternatives.
The input of the profiling functions. When we start profiling, we need a process descriptor for the local case or a server address (of the form "address:port") in the remote case. The creation of the process descriptor is aided by the Profiling.Heap.Process module.
The return value of the profiling functions. In the local case we are given the handle of the process monitored. Asking for a remote profile gives us a handle we can use to communicate with the proxy via the common protocol defined in the Profiling.Heap.Network module.
In order to perform real-time profiling, we need to fire up the
program to analyse and create an accumulator in the background that we
can look at whenever we want using the reading action returned by the
function. We are also given a stopping action and the handle to the
slave process or network connection depending on the type of
profiling. If there is a problem,
Nothing is returned.
profileCallback function initiates an observation without
maintaining any internal data other than the name mapping, passing
profile samples to the callback (provided in the second argument) as
they come. It returns the handle of the new process or the remote
connection as well as the thread stopper action, assuming that a heap
profile could be found.