memory-management - 如何衡量 Erlang 垃圾收集器的性能?

标签 memory-management garbage-collection erlang

我最近开始使用 Erlang 进行编程,关于垃圾收集 (GC),我想了解一些事情。据我了解,每个进程的私有(private)堆都有一个分代GC,全局共享堆有一个引用计数GC。
我想知道的是是否有任何办法得到:

  • 多少个收集周期?
  • 在全局级别或进程级别上分配和释放了多少字节?
  • 什么是私有(private)堆和共享堆大小?我们可以将其定义为 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,[]}]
    

    进程的收集周期数可在 minor_gcs 字段中找到。在 garbage_collection 部分下.
  • 每个进程

    进程的当前堆大小在字段 heap_size 中可用。从上面的结果(换句话说,在 32 位 VM 上为 4 个字节,在 64 位 VM 上为 8 个字节)。调用erlang:process_info(Pid, memory)可以得到进程的总内存消耗例如返回 {memory,34312}对于上述过程。这包括调用栈、堆和内部结构。

    可以使用 erlang:trace/3 跟踪重新分配(和分配)。 .如果跟踪标志是 garbage_collection您将收到格式为 {trace, Pid, gc_start, Info} 的消息和 {trace, Pid, gc_end, Info} . Info gc_start 的字段消息包含 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... 控制全局 VM 内存分配。 Erlang VM 的选项。标志描述here .但是,这需要对 Erlang VM 及其分配器的内部有广泛的了解,并且不应掉以轻心。
  • 这可以通过答案 2 中描述的跟踪来获得。如果您使用选项 timestamp跟踪时,您将收到每个跟踪消息的时间戳,可用于计算总 GC 时间。
  • 简短的回答:没有。

    长答案:也许。您可以控制初始堆大小(通过 min_heap_size ),这将影响首次进行垃圾回收的时间。您还可以使用 fullsweep_after 控制何时执行完整扫描。选项。

  • 更多信息请访问 Academic and Historical QuestionsProcesses效率指南的部分。

    在运行时内省(introspection) Erlang 内存使用的最实用方法是通过 Recon library ,如 Steve Vinoski mentioned .

    关于memory-management - 如何衡量 Erlang 垃圾收集器的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32669870/

    相关文章:

    Android:Eclipse MAT 似乎没有显示我应用程序的所有对象

    objective-c - cocoa : Objects allocated but not properly accessible?

    允许死内存的Java垃圾收集?

    Java 堆大小 - 没有 AdaptiveSizePolicy 的年轻代大小

    c# - 为什么 try/finally block 的存在会阻止垃圾收集器工作?

    c++ - C++在哪里调用析构函数?

    c++ - 让 shared_ptr 拥有现有指针的更简单方法

    erlang - 命令 'generate' 不理解或不适用

    Erlang 错误在 #Port 上收到意外的 tcp 数据

    erlang - Erlang中的函数链接