Memory management 如何度量Erlang垃圾收集器的性能?

Memory management 如何度量Erlang垃圾收集器的性能?,memory-management,garbage-collection,erlang,Memory Management,Garbage Collection,Erlang,我最近开始使用Erlang编程,关于垃圾收集(GC),我想了解一些事情。据我所知,每个进程的私有堆有一个分代GC,全局共享堆有一个引用计数GC 我想知道的是,是否还有其他方法可以获得: 有多少个收集周期 在全局级别或进程级别分配和释放多少字节 私有堆和共享堆的大小是多少?我们能把它定义为GC参数吗 收集垃圾需要多长时间?所需时间的百分比 有没有办法在没有GC的情况下运行程序 当我运行Erlang程序时,有没有一种方法可以通过代码或使用一些命令来获取此类信息 谢谢 要获取单个进程的信息,可以调用e

我最近开始使用Erlang编程,关于垃圾收集(GC),我想了解一些事情。据我所知,每个进程的私有堆有一个分代GC,全局共享堆有一个引用计数GC

我想知道的是,是否还有其他方法可以获得:

  • 有多少个收集周期
  • 在全局级别或进程级别分配和释放多少字节
  • 私有堆和共享堆的大小是多少?我们能把它定义为GC参数吗
  • 收集垃圾需要多长时间?所需时间的百分比
  • 有没有办法在没有GC的情况下运行程序
  • 当我运行Erlang程序时,有没有一种方法可以通过代码或使用一些命令来获取此类信息

    谢谢

  • 要获取单个进程的信息,可以调用
    erlang:process\u info(Pid)
    。这将产生(从Erlang 18.0开始)以下字段:

    erlang:process_info(self())。 [{current_函数,{erl_eval,do_apply,6}}, {initial_call,{erlang,apply,2}}, {状态,正在运行}, {消息队列,0}, {消息,[]}, {links,[]}, {字典,[]}, {trap_exit,false}, {error\u handler,error\u handler}, {优先级,正常}, {小组组长,}, {总堆大小,4184}, {heap_size,2586}, {堆栈大小,24}, {减少,3707}, {垃圾收集,[{min_bin_vheap_size,46422}, {min_heap_size,233}, {fullsweep_after,65535}, {minor_gcs,7}]}, {挂起,[]}] 在
    垃圾收集
    一节下的
    次要垃圾收集
    字段中可以找到该进程的收集周期数

  • 每个流程

    从上面的结果可以在
    heap\u size
    字段中找到进程的当前堆大小(换句话说,32位VM上有4个字节,64位VM上有8个字节)。通过调用
    erlang:process_info(Pid,memory)
    可以获得进程的总内存消耗量,该函数返回上述进程的
    {memory,34312}
    。这包括调用堆栈、堆和内部结构

    可以使用跟踪解除分配(和分配)。如果跟踪标志是
    garbage\u collection
    ,您将收到
    {trace,Pid,gc\u start,Info}
    {trace,Pid,gc\u end,Info}
    格式的消息。
    gc\u start
    消息的
    Info
    字段包含
    heap\u size
    old\u heap\u size
    等内容

    每个系统

    系统的顶级统计数据可通过以下方式获得:

    >erlang:memory()。
    [{总计15023008},
    {进程,4215272},
    {使用的进程,4215048},
    {system,10807736},
    {原子,202481},
    {atom_used,187597},
    {binary,325816},
    {代码4575293},
    {ets,234816}]
    
    垃圾收集统计信息可通过以下方式获得:

    >统计信息(垃圾收集)。
    {85,23961,0}
    
    其中(从Erlang 18.0开始),第一个字段是VM执行的垃圾收集总数,第二个字段是回收的字总数

  • 进程的堆大小可在上面进程信息的
    total\u heap\u size
    (所有堆片段和堆栈)和
    heap\u size
    (最年轻的堆生成的大小)字段下找到

    它们可以通过设置进程初始堆大小的
    min\u heap\u size
    来控制

    要为所有进程设置它,可以调用
    erlang:system\u标志(最小堆大小,最小堆大小)

    您还可以通过Erlang VM的
    +M..
    选项控制全局VM内存分配。对这些标志进行了描述。然而,这需要对ErlangVM及其分配器的内部结构有广泛的了解,使用它们不应掉以轻心

  • 这可以通过回答2中所述的跟踪来获得。如果在跟踪时使用选项
    timestamp
    ,您将收到每个跟踪消息的时间戳,可用于计算总GC时间

  • 简短回答:没有

    长回答:也许吧。您可以控制初始堆大小(通过
    min\u heap\u size
    ),这将影响首次进行垃圾回收的时间。您还可以使用
    fullsweep\u after
    选项控制何时执行完全扫描

  • 更多信息请参见《效率指南》的和部分


    运行时内省Erlang内存使用情况的最实用的方法是通过,as.

    我建议阅读并查看,这两种方法都是由Fred Hébert提供的,他也是本书的作者。了解您为什么问这个问题会很有趣。例如,您当前的Erlang应用程序是否存在GC问题,或者您是否有过类似Java等其他语言的令人失望的体验。请记住,对于Java,Erlang GC是每个Erlang进程的,而GC是每个JVM的。这意味着行为完全不同。Erlang从来不会生成一个大型GC。“记住,Erlang GC是每个Erlang进程的,而GC是每个Java JVM的”——我很清楚这一点,谢谢!我只是想了解Erlang的GC协议有多好。为此,我想尝试使用此类信息进行一些基准测试。顺便说一句,如果你知道关于Erlang的任何相关和有趣的基准,请让我知道。好的franco。当越来越多的人意识到每个JVM的GC是一个真正的问题时,看到这一点将是很有趣的。即使使用“现代”GC-like generational,您通常每天都会有一次完全停止,GC会阻塞系统10到100秒。就堆大小而言,GC不是线性过程这一事实尚未影响系统设计