The module instrument
contains support for studying the resource
usage in an Erlang runtime system. Currently, only the allocation of memory can
be studied.
Note that this whole module is experimental, and the representations used as well as the functionality is likely to change in the future. |
Some of the functions in this module are only available in Erlang
compiled with instrumentation; otherwise they exit with badarg
.
This is noted below for the individual functions. To start an Erlang runtime
system with instrumentation, use the command-line option -instr
to the erl
command.
The basic object of study in the case of memory allocation is a memory allocation list, which contains one descriptor for each allocated memory block. Currently, a descriptor is a 4-tuple
{Type, Address, Size, Pid}
where Type
indicates what the block is used for, Address
is its place in memory, and Size
is its size, in bytes.
Pid
is either undefined
(if the block was allocated by the
runtime system itself) or a tuple {A,B,C}
representing the
process which allocated the block, which corresponds to a pid with the
user-visible representation <A.B.C>
(the function c:pid/3
can be used to transform the numbers to a real pid).
Various details about memory allocation:
On Unix (for example, Solaris), memory for a process is allocated
linearly, usually from 0. The current size of the process cannot be
obtained from within Erlang, but can be seen with one of the system
statistics tools, e.g., ps
or top
. (There may be a hole
above the highest used memory block; in that case the functions in the
instrument
module cannot tell you about it; you have to compare
the High
value from mem_limits/1
with the value which the
system reports for Erlang.)
In the memory allocation list, certain small objects do not show up individually, since they are allocated from blocks of 20 objects (called "fixalloc" blocks). The blocks themselves do show up, but the amount of internal fragmentation in them currently cannot be observed.
Overhead for instrumentation: instrumented memory allocation uses 28 bytes extra for each block. The time overhead for managing the list is negligible.
AllocList = [Desc]
Desc = {int(), int(), int(), pid_tuple()}
pid_tuple() = {int(), int(), int()}
Prints out the size of each hole (i.e., the space between
allocated blocks) on the terminal.
The list must be sorted (see sort/1
).
mem_limits(AllocList) -> {Low, High}
AllocList = [Desc]
Desc = {int(), int(), int(), pid_tuple()}
pid_tuple() = {int(), int(), int()}
Low = High = int()
returns a tuple {Low, High}
indicating
the lowest and highest address used.
The list must be sorted (see sort/1
).
AllocList = [Desc]
Desc = {int(), int(), int(), pid_tuple()}
pid_tuple() = {int(), int(), int()}
Returns the memory allocation list. Only available in an Erlang runtime system compiled for instrumentation. Blocks execution of other processes while the list is collected.
read_memory_data(File) -> {ok, AllocList} | {error, Reason}
File = string()
AllocList = [Desc]
Desc = {int(), int(), int(), pid_tuple()}
pid_tuple() = {int(), int(), int()}
Reads a memory allocation list from the file File
.
The file is assumed to have been created by store_memory_data/1
.
The error codes are the same as for file:consult/1
.
AllocList = [Desc]
Desc = {int(), int(), int(), pid_tuple()}
pid_tuple() = {int(), int(), int()}
Sorts a memory allocation list so the addresses are in ascending order. The list arguments to many of the functions in this module must be sorted. No other function in this module returns a sorted list.
File = string()
Stores the memory allocation list on the file File
.
The contents of the file can later be read using
read_memory_data/1
. Only available in an Erlang runtime system
compiled for instrumentation. Blocks execution of other
processes while the list is collected (the time to write the
data is around 0.1 ms/line on a Sun Ultra 1).
Failure: badarg
if the file could not be written.
sum_blocks(AllocList) -> int()
AllocList = [Desc]
Desc = {int(), int(), int(), pid_tuple()}
pid_tuple() = {int(), int(), int()}
Returns the total size of the memory blocks in the list.
The list must be sorted (see sort/1
).
Type = int()
Translates a memory block type number into a readable string, which is a short description of the block type.
Failure: badarg
if the argument is not a
valid block type number.