给具有数据的ETS表,info/1函数将返回表的各种属性,包括大小值,该值特定于行数而不是物理大小。

有什么方法可以计算ETS表占用的内存量(以字节为单位)吗?

ets:new( mytable, [bag, named_table, compressed]),
ets:insert( mytable, { Key, Value } ),
....
ets:info ( mytable ).

最佳答案

TL; DR:

ETS表分配的内存大小(以字节为单位):
ets:info(Table,memory) * erlang:system_info(wordsize).
为了详细说明,ets:info(Table,memory)为您提供了分配给ETS表中数据的单词
(与Mnesia相同。您可以在TV应用程序中查看所有该信息。DETS表的相同属性以字节为单位)。

一个字只不过是特定CPU体系结构的“自然”数据单元。表示什么取决于您的体系结构:32位或64位(或使用erlang:system_info(wordsize)立即获取正确的字长)

  • 32位系统上,一个字为4字节(32位)。
  • 64位系统上,一个字为8字节(64位)。

  • 还要注意,ETS表initially spans 768 words必须添加每个元素的大小,即6个单词+ Erlang数据的大小。目前还不清楚ets:info是否指定了“分配给数据”一词。

    计算确切的大小有点麻烦:ETS表具有自己的独立内存管理系统,该系统已经过优化和垃圾回收,并且可以根据表类型(setbagduplicate_bag)而有所不同。作为实验,在我的环境中,一个空表返回300个单词“已分配给数据”。如果我添加11个元组,则大小增加到366个单词。根据定义,当它们应该是11 * 6 + 11 * 1(11个原子)时,不知道它们与最初的768个单词有什么关系,或者为什么大小仅增加11 * 6个单词。

    尽管如此,采用初始表大小和分配给数据的字(例如22086个字)的天真估计仍会导致768 * 8 + 22.086 * 8 = 182.832字节(178.54 KiB)。

    当然,数据越大,那些“结构”字的重要性就越小,因此您只能使用ets:info返回的“分配给数据的字”数字来估计表在内存中的大小。

    编辑:还有两个其他功能可让您审核ETS内存使用情况:
  • erlang:memory/1:erlang:memory(ets)返回分配给ETS的内存大小(以字节为单位)。
  • ets:i/0:所有事件ETS表的概述(有点像在TV中查看系统表,但具有类型和内存数据)。

  • 作为一个小测试,一个新创建的空表增加了312个单词(2.44 KiB)的内存使用量,比手册中的768个数字少得多(也许与CPU体系结构有关,我不知道),而ETS本身报告了299个单词(2.33 KiB)分配给数据。

    与所报告的erlang:memory/1增量相比,这仅占结构开销的13个字(104字节)(或者看起来仍然模糊),因此ets:info/2毕竟是相当准确的。

    插入一个由2个原子组成的简单元组后,erlang:memory/1报告增加了8个字的内存分配,就像文档所说的那样(新的ETS记录:6个字+数据大小-在这种情况下为2个:每个原子1个字) 。

    关于erlang - 如何确定ETS表的确切内存大小?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21973760/

    10-13 02:06