aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tools/doc/src/instrument.xml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tools/doc/src/instrument.xml')
-rw-r--r--lib/tools/doc/src/instrument.xml432
1 files changed, 432 insertions, 0 deletions
diff --git a/lib/tools/doc/src/instrument.xml b/lib/tools/doc/src/instrument.xml
new file mode 100644
index 0000000000..12877994de
--- /dev/null
+++ b/lib/tools/doc/src/instrument.xml
@@ -0,0 +1,432 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1998</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>instrument</title>
+ <prepared>Arndt Jonasson</prepared>
+ <responsible>Torbj&ouml;rn Johnsson</responsible>
+ <docno>1</docno>
+ <approved>Bj&ouml;rn Gustavsson</approved>
+ <checked></checked>
+ <date>98-04-01</date>
+ <rev>PA1</rev>
+ <file>instrument.sgml</file>
+ </header>
+ <module>instrument</module>
+ <modulesummary>Analysis and Utility Functions for Instrumentation</modulesummary>
+ <description>
+ <p>The module <c>instrument</c> contains support for studying the resource
+ usage in an Erlang runtime system. Currently, only the allocation of memory can
+ be studied.</p>
+ <note>
+ <p>Note that this whole module is experimental, and the representations
+ used as well as the functionality is likely to change in the future.</p>
+ <p>The <c>instrument</c> module interface was slightly changed in
+ Erlang/OTP R9C.</p>
+ </note>
+ <p>To start an Erlang runtime system with instrumentation, use the
+ <c>+Mi*</c> set of command-line arguments to the <c>erl</c> command (see
+ the erts_alloc(3) and erl(1) man pages).</p>
+ <p>The basic object of study in the case of memory allocation is a memory
+ allocation map. A memory allocation map contains a list of descriptors
+ for each allocated memory block. Currently, a descriptor is a 4-tuple</p>
+ <pre>
+ {TypeNo, Address, Size, PidDesc} </pre>
+ <p>where <c>TypeNo</c> is the memory block type number, <c>Address</c>
+ is its place in memory, and <c>Size</c> is its size, in bytes.
+ <c>PidDesc</c> is either a tuple <c>{X,Y,Z}</c> identifying the
+ process which was executing when the block was allocated, or
+ <c>undefined</c> if no process was executing. The pid tuple
+ <c>{X,Y,Z}</c> can be transformed into a real pid by usage of the
+ <c>c:pid/3</c> function.</p>
+ <p>Various details about memory allocation:</p>
+ <p>Memory blocks are allocated both on the heap segment and on other memory
+ segments. This can cause the instrumentation functionality to report
+ very large holes. Currently the instrumentation functionality doesn't
+ provide any support for distinguishing between holes between memory
+ segments, and holes between allocated blocks inside memory segments.
+ 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.,
+ <c>ps</c> or <c>top</c>. The Solaris utility <c>pmap</c> can be
+ useful. It reports currently mapped memory segments. </p>
+ <p>Overhead for instrumentation: When the emulator has been started with
+ the <seealso marker="erts:erts_alloc#Mim">"+Mim true"</seealso>
+ flag, each block is preceded by a 24 bytes large
+ header on a 32-bit machine and a 48 bytes large header on a 64-bit
+ machine. When the emulator has been started with the
+ <seealso marker="erts:erts_alloc#Mis">"+Mis true"</seealso>
+ flag, each block is preceded by an 8 bytes large header. These are the header
+ sizes used by the Erlang 5.3/OTP R9C emulator. Other versions of the
+ emulator may use other header sizes. The function
+ <seealso marker="#block_header_size/1">block_header_size/1</seealso>
+ can be used for retrieving the header size used for a specific memory
+ allocation map. The time overhead for managing the instrumentation
+ data is small.</p>
+ <p>Sizes presented by the instrumentation functionality are (by the
+ emulator) requested sizes, i.e. neither instrumentation headers nor
+ headers used by allocators are included.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>allocator_descr(MemoryData, TypeNo) -> AllocDescr | invalid_type | "unknown"</name>
+ <fsummary>Returns a allocator description</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>TypeNo = int()</v>
+ <v>AllocDescr = atom() | string()</v>
+ </type>
+ <desc>
+ <p>Returns the allocator description of the allocator that
+ manages memory blocks of type number <c>TypeNo</c> used in
+ <c>MemoryData</c>.
+ Valid <c>TypeNo</c>s are in the range returned by
+ <seealso marker="#type_no_range/1">type_no_range/1</seealso> on
+ this specific memory allocation map. If <c>TypeNo</c> is an
+ invalid integer, <c>invalid_type</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>block_header_size(MemoryData) -> int()</name>
+ <fsummary>Returns the memory block header size used by the emulator that generated the memory allocation map</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <marker id="block_header_size_1"></marker>
+ <p>Returns the memory block header size used by the
+ emulator that generated the memory allocation map. The block
+ header size may differ between different emulators.</p>
+ </desc>
+ </func>
+ <func>
+ <name>class_descr(MemoryData, TypeNo) -> ClassDescr | invalid_type | "unknown"</name>
+ <fsummary>Returns a allocator description</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>TypeNo = int()</v>
+ <v>ClassDescr = atom() | string()</v>
+ </type>
+ <desc>
+ <p>Returns the class description of the class that
+ the type number <c>TypeNo</c> used in <c>MemoryData</c> belongs
+ to.
+ Valid <c>TypeNo</c>s are in the range returned by
+ <seealso marker="#type_no_range/1">type_no_range/1</seealso> on
+ this specific memory allocation map. If <c>TypeNo</c> is an
+ invalid integer, <c>invalid_type</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>descr(MemoryData) -> DescrMemoryData</name>
+ <fsummary>Replace type numbers in memory allocation map with type descriptions</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>DescrMemoryData = {term(), DescrAllocList}</v>
+ <v>DescrAllocList = [DescrDesc]</v>
+ <v>DescrDesc = {TypeDescr, int(), int(), DescrPidDesc}</v>
+ <v>TypeDescr = atom() | string()</v>
+ <v>DescrPidDesc = pid() | undefined</v>
+ </type>
+ <desc>
+ <p>Returns a memory allocation map where the type numbers (first
+ element of <c>Desc</c>) have been replaced by type descriptions,
+ and pid tuples (fourth element of <c>Desc</c>) have been
+ replaced by real pids.</p>
+ </desc>
+ </func>
+ <func>
+ <name>holes(MemoryData) -> ok</name>
+ <fsummary>Print out the sizes of unused memory blocks</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <p>Prints out the size of each hole (i.e., the space between
+ allocated blocks) on the terminal. <em>NOTE:</em> Really large holes
+ are probably holes between memory segments.
+ The memory allocation map has to be sorted (see
+ <seealso marker="#sort/1">sort/1</seealso>).</p>
+ </desc>
+ </func>
+ <func>
+ <name>mem_limits(MemoryData) -> {Low, High}</name>
+ <fsummary>Return lowest and highest memory address used</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>Low = High = int()</v>
+ </type>
+ <desc>
+ <p>Returns a tuple <c>{Low, High}</c> indicating
+ the lowest and highest address used.
+ The memory allocation map has to be sorted (see
+ <seealso marker="#sort/1">sort/1</seealso>).</p>
+ </desc>
+ </func>
+ <func>
+ <name>memory_data() -> MemoryData | false</name>
+ <fsummary>Return the current memory allocation map</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <p>Returns <c>MemoryData</c> (a the memory allocation map)
+ if the emulator has been started with the "<c>+Mim true</c>"
+ command-line argument; otherwise, <c>false</c>. <em>NOTE:</em><c>memory_data/0</c> blocks execution of other processes while
+ the data is collected. The time it takes to collect the data can
+ be substantial.</p>
+ </desc>
+ </func>
+ <func>
+ <name>memory_status(StatusType) -> [StatusInfo] | false</name>
+ <fsummary>Return current memory allocation status</fsummary>
+ <type>
+ <v>StatusType = total | allocators | classes | types</v>
+ <v>StatusInfo = {About, [Info]}</v>
+ <v>About = atom()</v>
+ <v>Info = {InfoName, Current, MaxSinceLast, MaxEver}</v>
+ <v>InfoName = sizes|blocks</v>
+ <v>Current = int()</v>
+ <v>MaxSinceLast = int()</v>
+ <v>MaxEver = int()</v>
+ </type>
+ <desc>
+ <p>Returns a list of <c>StatusInfo</c> if the emulator has been
+ started with the "<c>+Mis true</c>" or "<c>+Mim true</c>"
+ command-line argument; otherwise, <c>false</c>. </p>
+ <p>See the
+ <seealso marker="#read_memory_status/1">read_memory_status/1</seealso>
+ function for a description of the <c>StatusInfo</c> term.</p>
+ </desc>
+ </func>
+ <func>
+ <name>read_memory_data(File) -> MemoryData | {error, Reason}</name>
+ <fsummary>Read memory allocation map</fsummary>
+ <type>
+ <v>File = string()</v>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <marker id="read_memory_data_1"></marker>
+ <p>Reads a memory allocation map from the file <c>File</c> and
+ returns it. The file is assumed to have been created by
+ <c>store_memory_data/1</c>. The error codes are the same as for
+ <c>file:consult/1</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>read_memory_status(File) -> MemoryStatus | {error, Reason}</name>
+ <fsummary>Read memory allocation status from a file</fsummary>
+ <type>
+ <v>File = string()</v>
+ <v>MemoryStatus = [{StatusType, [StatusInfo]}]</v>
+ <v>StatusType = total | allocators | classes | types</v>
+ <v>StatusInfo = {About, [Info]}</v>
+ <v>About = atom()</v>
+ <v>Info = {InfoName, Current, MaxSinceLast, MaxEver}</v>
+ <v>InfoName = sizes|blocks</v>
+ <v>Current = int()</v>
+ <v>MaxSinceLast = int()</v>
+ <v>MaxEver = int()</v>
+ </type>
+ <desc>
+ <marker id="read_memory_status_1"></marker>
+ <p>Reads memory allocation status from the file <c>File</c> and
+ returns it. The file is assumed to have been created by
+ <c>store_memory_status/1</c>. The error codes are the same as
+ for <c>file:consult/1</c>.</p>
+ <p>When <c>StatusType</c> is <c>allocators</c>, <c>About</c> is
+ the allocator that the information is about. When
+ <c>StatusType</c> is <c>types</c>, <c>About</c> is
+ the memory block type that the information is about. Memory
+ block types are not described other than by their name and may
+ vary between emulators. When <c>StatusType</c> is <c>classes</c>,
+ <c>About</c> is the memory block type class that information is
+ presented about. Memory block types are classified after their
+ use. Currently the following classes exist:</p>
+ <taglist>
+ <tag><c>process_data</c></tag>
+ <item>Erlang process specific data.</item>
+ <tag><c>binary_data</c></tag>
+ <item>Erlang binaries.</item>
+ <tag><c>atom_data</c></tag>
+ <item>Erlang atoms.</item>
+ <tag><c>code_data</c></tag>
+ <item>Erlang code.</item>
+ <tag><c>system_data</c></tag>
+ <item>Other data used by the system</item>
+ </taglist>
+ <p>When <c>InfoName</c> is <c>sizes</c>, <c>Current</c>,
+ <c>MaxSinceLast</c>, and <c>MaxEver</c> are, respectively, current
+ size, maximum size since last call to
+ <c>store_memory_status/1</c> or <c>memory_status/1</c> with the
+ specific <c>StatusType</c>, and maximum size since the emulator
+ was started. When <c>InfoName</c> is <c>blocks</c>, <c>Current</c>,
+ <c>MaxSinceLast</c>, and <c>MaxEver</c> are, respectively, current
+ number of blocks, maximum number of blocks since last call to
+ <c>store_memory_status/1</c> or <c>memory_status/1</c> with the
+ specific <c>StatusType</c>, and maximum number of blocks since the
+ emulator was started. </p>
+ <p><em>NOTE:</em>A memory block is accounted for at
+ "the first level" allocator. E.g. <c>fix_alloc</c> allocates its
+ memory pools via <c>ll_alloc</c>. When a <c>fix_alloc</c> block
+ is allocated, neither the block nor the pool in which it resides
+ are accounted for as memory allocated via <c>ll_alloc</c> even
+ though it is.</p>
+ </desc>
+ </func>
+ <func>
+ <name>sort(MemoryData) -> MemoryData</name>
+ <fsummary>Sort the memory allocation list</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <marker id="sort_1"></marker>
+ <p>Sorts a memory allocation map so that the addresses are in
+ ascending order.</p>
+ </desc>
+ </func>
+ <func>
+ <name>store_memory_data(File) -> true|false</name>
+ <fsummary>Store the current memory allocation map on a file</fsummary>
+ <type>
+ <v>File = string()</v>
+ </type>
+ <desc>
+ <p>Stores the current memory allocation map on the file
+ <c>File</c>. Returns <c>true</c> if the emulator has been
+ started with the "<c>+Mim true</c>" command-line argument, and
+ the map was successfuly stored; otherwise, <c>false</c>. The
+ contents of the file can later be read using
+ <seealso marker="#read_memory_data/1">read_memory_data/1</seealso>.
+ <em>NOTE:</em><c>store_memory_data/0</c> blocks execution of
+ other processes while the data is collected. The time it takes
+ to collect the data can be substantial.</p>
+ </desc>
+ </func>
+ <func>
+ <name>store_memory_status(File) -> true|false</name>
+ <fsummary>Store the current memory allocation status on a file</fsummary>
+ <type>
+ <v>File = string()</v>
+ </type>
+ <desc>
+ <p>Stores the current memory status on the file
+ <c>File</c>. Returns <c>true</c> if the emulator has been
+ started with the "<c>+Mis true</c>", or "<c>+Mim true</c>"
+ command-line arguments, and the data was successfuly stored;
+ otherwise, <c>false</c>. The contents of the file can later be
+ read using
+ <seealso marker="#read_memory_status/1">read_memory_status/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>sum_blocks(MemoryData) -> int()</name>
+ <fsummary>Return the total amount of memory used</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <p>Returns the total size of the memory blocks in the list.</p>
+ </desc>
+ </func>
+ <func>
+ <name>type_descr(MemoryData, TypeNo) -> TypeDescr | invalid_type</name>
+ <fsummary>Returns a type description</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>TypeNo = int()</v>
+ <v>TypeDescr = atom() | string()</v>
+ </type>
+ <desc>
+ <p>Returns the type description of a type number used in
+ <c>MemoryData</c>.
+ Valid <c>TypeNo</c>s are in the range returned by
+ <seealso marker="#type_no_range/1">type_no_range/1</seealso> on
+ this specific memory allocation map. If <c>TypeNo</c> is an
+ invalid integer, <c>invalid_type</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>type_no_range(MemoryData) -> {Min, Max}</name>
+ <fsummary>Returns the memory block type numbers</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>Min = int()</v>
+ <v>Max = int()</v>
+ </type>
+ <desc>
+ <marker id="type_no_range_1"></marker>
+ <p>Returns the memory block type number range used in
+ <c>MemoryData</c>. When the memory allocation map was generated
+ by an Erlang 5.3/OTP R9C or newer emulator, all integers <c>T</c>
+ that satisfy <c>Min</c> &lt;= <c>T</c> &lt;= <c>Max</c> are
+ valid type numbers. When the memory allocation map was generated
+ by a pre Erlang 5.3/OTP R9C emulator, all integers in the
+ range are <em>not</em> valid type numbers.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p><seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>,
+ <seealso marker="erts:erl">erl(1)</seealso></p>
+ </section>
+</erlref>
+