How to identify the exact memory size of an ETS table?

五迷三道 提交于 2019-12-09 16:26:38

问题


Give an ETS table with data, the info/1 function returns various properties for the table, including a size value which is specific to the number of rows rather than the physical size.

Is there any way to calculate the amount of memory in bytes occupied by an ETS table ?

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

回答1:


TL;DR:

ETS table allocated memory size in bytes:

ets:info(Table,memory) * erlang:system_info(wordsize).


To elaborate a bit, ets:info(Table,memory) gives you the words allocated to data in an ETS table (same for Mnesia. You can view al that info in the TV application. The same attribute for DETS tables is in bytes).

A word is nothing more than the 'natural' data unit of a particular CPU architecture. What that represents depends on your architecture: 32-bit or 64-bit (or use erlang:system_info(wordsize) to get the correct word size immediately)

  • On a 32-bit system, a word is 4 bytes (32 bits).
  • On a 64-bit system, a word is 8 bytes (64 bits).

Also note that a ETS table initially spans 768 words, to wich you must add the size of each element, 6 words + size of Erlang data. It's not really clear if those are the words "allocated to data" ets:info specifies.

Calculating the exact size is a bit of a hassle: ETS tables have their own independent memory management system, which is optimized and garbage collected, and can vary depending on table type (set, bag, duplicate_bag). As an experiment, an empty table returns, in my environment, 300 words "allocated to data". If I add 11 tuples, size increases to 366 words. No Idea to how those relate to the initial 768 words, or why the size only increases by 11*6 words, when it should have been 11*6 + 11*1 (11 atoms), according to definition.

Still, a naive estimate, taking the initial table size and the words allocated to data, for example 22086 words, results in 768*8 + 22.086*8 = 182.832 bytes (178.54 KiB).

Of course, the bigger the data, the less those "structural" words matter, so you could only use the "words allocated to data" number, returned by ets:info, to estimate your table's size in memory.


Edit: There are two other functions that let you audit ETS memory usage:

  • erlang:memory/1: erlang:memory(ets) returns the memory size, in bytes, allocated to ETS.
  • ets:i/0: an overview of all active ETS tables (a bit like viewing system tables in TV, but with type and memory data).

As a small test, an newly created empty table increased memory use with 312 words (2.44 KiB), a lot less than the 768 number in the manual (perhaps it's CPU architecture related, I have no idea), while ETS itself reported 299 words (2.33 KiB) allocated to the data.

That's only 13 words (104 bytes) of structural overhead away (or so it seems, it remains nebulous) from the increase erlang:memory/1 reported, so ets:info/2 is fairly accurate after all.

After the insertion of a simple tuple consisting of 2 atoms, erlang:memory/1 reported a 8 word memory allocation increase, just like the documentation said it would (new ETS record: 6 words + size of data - 2 in this case : 1 word per atom).




回答2:


you can read the document about ets.

you can ues this to get the memory allocated to the table. ets:info ( mytable, memory).

{memory, integer() >= 0 The number of words allocated to the table.

|improve this answer

来源:https://stackoverflow.com/questions/21973760/how-to-identify-the-exact-memory-size-of-an-ets-table

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!