如何衡量 Erlang 垃圾收集器的性能?
How to measure the performance of the Erlang Garbage Collector?
我最近开始使用 Erlang 编程,关于垃圾收集 (GC),我想了解一些事情。据我了解,每个进程的私有堆有分代GC,全局共享堆有引用计数GC。
我想知道的是有没有办法得到:
- 收集周期是多少?
- 在全局级别或进程级别分配和释放了多少字节?
- 私有堆和共享堆的大小是多少?我们可以将其定义为 GC 参数吗?
- 收集垃圾需要多长时间?所需时间百分比?
- 有没有办法 运行 没有 GC 的程序?
当我 运行 一个 Erlang 程序时,有没有办法通过代码或使用一些命令来获取此类信息?
谢谢。
要获取单个进程的信息,可以调用erlang:process_info(Pid)
。这将产生(从 Erlang 18.0 开始)以下字段:
> erlang:process_info(self()).
[{current_function,{erl_eval,do_apply,6}},
{initial_call,{erlang,apply,2}},
{status,running},
{message_queue_len,0},
{messages,[]},
{links,[<0.27.0>]},
{dictionary,[]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.26.0>},
{total_heap_size,4184},
{heap_size,2586},
{stack_size,24},
{reductions,3707},
{garbage_collection,[{min_bin_vheap_size,46422},
{min_heap_size,233},
{fullsweep_after,65535},
{minor_gcs,7}]},
{suspending,[]}]
进程的收集周期数在 garbage_collection
部分下的字段 minor_gcs
中可用。
每个进程
进程的当前堆大小可在上面结果的 heap_size
字段中找到(换言之,32 位 VM 上为 4 个字节,64 位 VM 上为 8 个字节)。进程的总内存消耗可以通过调用 erlang:process_info(Pid, memory)
which returns example {memory,34312}
获取上述进程。这包括调用堆栈、堆和内部结构。
可以使用 erlang:trace/3
跟踪解除分配(和分配)。如果跟踪标志是 garbage_collection
,您将收到格式为 {trace, Pid, gc_start, Info}
和 {trace, Pid, gc_end, Info}
的消息。 gc_start
消息的 Info
字段包含 heap_size
和 old_heap_size
.
等内容
每个系统
系统的顶级统计信息可以通过erlang:memory/0
:
获得
> erlang:memory().
[{total,15023008},
{processes,4215272},
{processes_used,4215048},
{system,10807736},
{atom,202481},
{atom_used,187597},
{binary,325816},
{code,4575293},
{ets,234816}]
可以通过 erlang:statistics(garbage_collection)
获取垃圾收集统计信息,结果为:
> statistics(garbage_collection).
{85,23961,0}
其中(从 Erlang 18.0 开始)第一个字段是 VM 执行的垃圾收集总数,第二个字段是回收的单词总数。
进程的堆大小在字段 total_heap_size
(所有堆碎片和堆栈)和 heap_size
(最年轻堆的大小)下可用上面的过程信息。
它们可以通过 spawn options 控制,特别是 min_heap_size
设置进程的初始堆大小。
要为所有进程设置它,可以调用erlang:system_flag(min_heap_size, MinHeapSize)
。
您还可以通过 +M...
选项控制 Erlang VM 的全局 VM 内存分配。标志描述为 here。但是,这需要对 Erlang VM 及其分配器的内部结构有广泛的了解,使用它们时不应掉以轻心。
这可以通过答案2中描述的跟踪获得。如果您在跟踪时使用选项timestamp
,您将收到一个时间戳,每个跟踪消息可用于计算GC 总时间。
简答:没有。
长答案:也许吧。您可以控制初始堆大小(通过 min_heap_size
),这将影响第一次进行垃圾收集的时间。您还可以使用 fullsweep_after
选项控制何时执行全面扫描。
可以在效率指南的 Academic and Historical Questions and Processes 部分找到更多信息。
在运行时内省 Erlang 内存使用情况的最实用方法是通过 Recon library, as 。
我最近开始使用 Erlang 编程,关于垃圾收集 (GC),我想了解一些事情。据我了解,每个进程的私有堆有分代GC,全局共享堆有引用计数GC。
我想知道的是有没有办法得到:
- 收集周期是多少?
- 在全局级别或进程级别分配和释放了多少字节?
- 私有堆和共享堆的大小是多少?我们可以将其定义为 GC 参数吗?
- 收集垃圾需要多长时间?所需时间百分比?
- 有没有办法 运行 没有 GC 的程序?
当我 运行 一个 Erlang 程序时,有没有办法通过代码或使用一些命令来获取此类信息?
谢谢。
要获取单个进程的信息,可以调用
erlang:process_info(Pid)
。这将产生(从 Erlang 18.0 开始)以下字段:> erlang:process_info(self()). [{current_function,{erl_eval,do_apply,6}}, {initial_call,{erlang,apply,2}}, {status,running}, {message_queue_len,0}, {messages,[]}, {links,[<0.27.0>]}, {dictionary,[]}, {trap_exit,false}, {error_handler,error_handler}, {priority,normal}, {group_leader,<0.26.0>}, {total_heap_size,4184}, {heap_size,2586}, {stack_size,24}, {reductions,3707}, {garbage_collection,[{min_bin_vheap_size,46422}, {min_heap_size,233}, {fullsweep_after,65535}, {minor_gcs,7}]}, {suspending,[]}]
进程的收集周期数在
garbage_collection
部分下的字段minor_gcs
中可用。每个进程
进程的当前堆大小可在上面结果的
heap_size
字段中找到(换言之,32 位 VM 上为 4 个字节,64 位 VM 上为 8 个字节)。进程的总内存消耗可以通过调用erlang:process_info(Pid, memory)
which returns example{memory,34312}
获取上述进程。这包括调用堆栈、堆和内部结构。可以使用
等内容erlang:trace/3
跟踪解除分配(和分配)。如果跟踪标志是garbage_collection
,您将收到格式为{trace, Pid, gc_start, Info}
和{trace, Pid, gc_end, Info}
的消息。gc_start
消息的Info
字段包含heap_size
和old_heap_size
.每个系统
系统的顶级统计信息可以通过
获得erlang:memory/0
:> erlang:memory(). [{total,15023008}, {processes,4215272}, {processes_used,4215048}, {system,10807736}, {atom,202481}, {atom_used,187597}, {binary,325816}, {code,4575293}, {ets,234816}]
可以通过
erlang:statistics(garbage_collection)
获取垃圾收集统计信息,结果为:> statistics(garbage_collection). {85,23961,0}
其中(从 Erlang 18.0 开始)第一个字段是 VM 执行的垃圾收集总数,第二个字段是回收的单词总数。
进程的堆大小在字段
total_heap_size
(所有堆碎片和堆栈)和heap_size
(最年轻堆的大小)下可用上面的过程信息。它们可以通过 spawn options 控制,特别是
min_heap_size
设置进程的初始堆大小。要为所有进程设置它,可以调用
erlang:system_flag(min_heap_size, MinHeapSize)
。您还可以通过
+M...
选项控制 Erlang VM 的全局 VM 内存分配。标志描述为 here。但是,这需要对 Erlang VM 及其分配器的内部结构有广泛的了解,使用它们时不应掉以轻心。这可以通过答案2中描述的跟踪获得。如果您在跟踪时使用选项
timestamp
,您将收到一个时间戳,每个跟踪消息可用于计算GC 总时间。简答:没有。
长答案:也许吧。您可以控制初始堆大小(通过
min_heap_size
),这将影响第一次进行垃圾收集的时间。您还可以使用fullsweep_after
选项控制何时执行全面扫描。
可以在效率指南的 Academic and Historical Questions and Processes 部分找到更多信息。
在运行时内省 Erlang 内存使用情况的最实用方法是通过 Recon library, as