.TH instrument 3erl "tools 3.5.3" "Ericsson AB" "Erlang Module Definition" .SH NAME instrument \- Analysis and Utility Functions for Instrumentation .SH DESCRIPTION .LP The module \fIinstrument\fR\& contains support for studying the resource usage in an Erlang runtime system\&. Currently, only the allocation of memory can be studied\&. .LP .RS -4 .B Note: .RE Since this module inspects internal details of the runtime system it may differ greatly from one version to another\&. We make no compatibility guarantees in this module\&. .SH DATA TYPES .nf \fBblock_histogram()\fR\& = tuple() .br .fi .RS .LP A histogram of block sizes where each interval\&'s upper bound is twice as high as the one before it\&. .LP The upper bound of the first interval is provided by the function that returned the histogram, and the last interval has no upper bound\&. .LP For example, the histogram below has 40 (\fImessage\fR\&) blocks between 256-512 bytes in size, 78 blocks between 512-1024 bytes,2 blocks between 1-2KB, and 2 blocks between 2-4KB\&. .LP .nf > instrument:allocations(#{ histogram_start => 128, histogram_width => 15 }). {ok, {128, 0, #{ message => {0,40,78,2,2,0,0,0,0,0,0,0,0,0,0}, ... } }} .fi .RE .nf \fBallocation_summary()\fR\& = .br {HistogramStart :: integer() >= 0, .br UnscannedSize :: integer() >= 0, .br Allocations :: .br #{Origin :: atom() => .br #{Type :: atom() => block_histogram()}}} .br .fi .RS .LP A summary of allocated block sizes (including their headers) grouped by their \fIOrigin\fR\& and \fIType\fR\&\&. .LP \fIOrigin\fR\& is generally which NIF or driver that allocated the blocks, or \&'system\&' if it could not be determined\&. .LP \fIType\fR\& is the allocation category that the blocks belong to, e\&.g\&. \fIdb_term\fR\&, \fImessage\fR\& or \fIbinary\fR\&\&. The categories correspond to those in erl_alloc\&.types\&. .LP If one or more carriers could not be scanned in full without harming the responsiveness of the system, \fIUnscannedSize\fR\& is the number of bytes that had to be skipped\&. .RE .nf \fBcarrier_info_list()\fR\& = .br {HistogramStart :: integer() >= 0, .br Carriers :: .br [{AllocatorType :: atom(), .br InPool :: boolean(), .br TotalSize :: integer() >= 0, .br UnscannedSize :: integer() >= 0, .br Allocations :: .br {Type :: atom(), .br Count :: integer() >= 0, .br Size :: integer() >= 0}, .br FreeBlocks :: block_histogram()}]} .br .fi .RS .LP \fIAllocatorType\fR\& is the type of the allocator that employs this carrier\&. .LP \fIInPool\fR\& is whether the carrier is in the migration pool\&. .LP \fITotalSize\fR\& is the total size of the carrier, including its header\&. .LP \fIAllocations\fR\& is a summary of the allocated blocks in the carrier\&. Note that carriers may contain multiple different block types when carrier pools are shared between different allocator types (see the \fIerts_alloc\fR\& documentation for more details)\&. .LP \fIFreeBlocks\fR\& is a histogram of the free block sizes in the carrier\&. .LP If the carrier could not be scanned in full without harming the responsiveness of the system, \fIUnscannedSize\fR\& is the number of bytes that had to be skipped\&. .RE .SH EXPORTS .LP .nf .B allocations() -> {ok, Result} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Result = allocation_summary() .br Reason = not_enabled .br .RE .RE .RS .LP Shorthand for \fIallocations(#{})\fR\&\&. .RE .LP .nf .B allocations(Options) -> {ok, Result} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Result = allocation_summary() .br Reason = not_enabled .br Options = .br #{scheduler_ids => [integer() >= 0], .br allocator_types => [atom()], .br histogram_start => integer() >= 1, .br histogram_width => integer() >= 1} .br .RE .RE .RS .LP Returns a summary of all tagged allocations in the system, optionally filtered by allocator type and scheduler id\&. .LP Only binaries and allocations made by NIFs and drivers are tagged by default, but this can be configured an a per-allocator basis with the \fI+Matags\fR\& emulator option\&. .LP If the specified allocator types are not enabled, the call will fail with \fI{error, not_enabled}\fR\&\&. .LP The following options can be used: .RS 2 .TP 2 .B \fIallocator_types\fR\&: The allocator types that will be searched\&. .RS 2 .LP Specifying a specific allocator type may lead to strange results when carrier migration between different allocator types has been enabled: you may see unexpected types (e\&.g\&. process heaps when searching binary_alloc), or fewer blocks than expected if the carriers the blocks are on have been migrated out to an allocator of a different type\&. .RE .RS 2 .LP Defaults to all \fIalloc_util\fR\& allocators\&. .RE .TP 2 .B \fIscheduler_ids\fR\&: The scheduler ids whose allocator instances will be searched\&. A scheduler id of 0 will refer to the global instance that is not tied to any particular scheduler\&. Defaults to all schedulers and the global instance\&. .TP 2 .B \fIhistogram_start\fR\&: The upper bound of the first interval in the allocated block size histograms\&. Defaults to 128\&. .TP 2 .B \fIhistogram_width\fR\&: The number of intervals in the allocated block size histograms\&. Defaults to 18\&. .RE .LP \fIExample:\fR\& .LP .nf > instrument:allocations(#{ histogram_start => 128, histogram_width => 15 }). {ok,{128,0, #{udp_inet => #{driver_event_state => {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}}, system => #{heap => {0,0,0,0,20,4,2,2,2,3,0,1,0,0,1}, db_term => {271,3,1,52,80,1,0,0,0,0,0,0,0,0,0}, code => {0,0,0,5,3,6,11,22,19,20,10,2,1,0,0}, binary => {18,0,0,0,7,0,0,1,0,0,0,0,0,0,0}, message => {0,40,78,2,2,0,0,0,0,0,0,0,0,0,0}, ... } spawn_forker => #{driver_select_data_state => {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}, ram_file_drv => #{drv_binary => {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}}, prim_file => #{process_specific_data => {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, nif_trap_export_entry => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}, monitor_extended => {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, drv_binary => {0,0,0,0,0,0,1,0,3,5,0,0,0,1,0}, binary => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}}, prim_buffer => #{nif_internal => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}, binary => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}}}}} .fi .RE .LP .nf .B carriers() -> {ok, Result} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Result = carrier_info_list() .br Reason = not_enabled .br .RE .RE .RS .LP Shorthand for \fIcarriers(#{})\fR\&\&. .RE .LP .nf .B carriers(Options) -> {ok, Result} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Result = carrier_info_list() .br Reason = not_enabled .br Options = .br #{scheduler_ids => [integer() >= 0], .br allocator_types => [atom()], .br histogram_start => integer() >= 1, .br histogram_width => integer() >= 1} .br .RE .RE .RS .LP Returns a summary of all carriers in the system, optionally filtered by allocator type and scheduler id\&. .LP If the specified allocator types are not enabled, the call will fail with \fI{error, not_enabled}\fR\&\&. .LP The following options can be used: .RS 2 .TP 2 .B \fIallocator_types\fR\&: The allocator types that will be searched\&. Defaults to all \fIalloc_util\fR\& allocators\&. .TP 2 .B \fIscheduler_ids\fR\&: The scheduler ids whose allocator instances will be searched\&. A scheduler id of 0 will refer to the global instance that is not tied to any particular scheduler\&. Defaults to all schedulers and the global instance\&. .TP 2 .B \fIhistogram_start\fR\&: The upper bound of the first interval in the free block size histograms\&. Defaults to 512\&. .TP 2 .B \fIhistogram_width\fR\&: The number of intervals in the free block size histograms\&. Defaults to 14\&. .RE .LP \fIExample:\fR\& .LP .nf > instrument:carriers(#{ histogram_start => 512, histogram_width => 8 }). {ok,{512, [{driver_alloc,false,262144,0, [{driver_alloc,1,32784}], {0,0,0,0,0,0,0,1}}, {binary_alloc,false,32768,0, [{binary_alloc,15,4304}], {3,0,0,0,1,0,0,0}}, {...}|...]}} .fi .RE .SH "SEE ALSO" .LP erts_alloc(3erl), erl(1)