Ets memory occupy - the erL shell query occupies more than 2M memory, but the observer query occupies more than 18M memory

The following operation creates an ETS table and inserts 300,000 items of data.

T = ets:new(tttt, [named_table]).
_ = [ets:insert(T, {O, O}) || O ← lists:seq(1, 300000)].

Then the erL shell query occupies more than 2M memory, but the observer query occupies more than 18M memory. From the perspective of the operating system, it also occupies more than 18M memory

Feels like a lot of wasted space


I think the 18M of memory you are seeing are from the list comprehension and are held by _.

In the erlang terminal, after using _, you can still refer to the value by the line id (2> in the line below):

2> _ = [ets:insert(T, {O, O}) || O <- lists:seq(1, 300000)].  
3> v2().

Can you check if you see the same results with:

lists:foreach(fun(O) -> ets:insert(T, {O, O}) end, lists:seq(1, 300000)).  

This line of code doesn’t hold the return value of ets:insert in a variable so it won’t appear in observer.


There is also the option f() in the shell that will delete all the bind variables Erlang -- shell


  • The result is the same, I guess ETS has a mechanism for pre-allocating memory
1 Like

Sorry, I didn’t realise before. The memory in ets:info(Tab) is in words and not in bytes.

From the memory page:

…A word is therefore 4 bytes or 8 bytes, respectively. The value for a running system can be determined by calling erlang:system_info(wordsize).

Therefore, assuming your implementation uses a word size is 8 bytes the total number of bytes is 2401625 * 8 = 19213 kB.

It doesn’t totally match the observer value but it is not 2MB as you thought in the first comment. It would be interesting to know why it shows a different value.

1 Like

oh, it is the words, That’s right. 2401629 * 8 / 1024 = 18762.7265625 KB

thanks you all


Then observer should show MiB instead of MB :smile:


:grinning: :grinning: :grinning:

1 Like