Skip to content

Instantly share code, notes, and snippets.

@dszoboszlay
Last active February 8, 2019 22:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dszoboszlay/921b26a57463ec1f5df1816a840a78aa to your computer and use it in GitHub Desktop.
Save dszoboszlay/921b26a57463ec1f5df1816a840a78aa to your computer and use it in GitHub Desktop.
ETS memory fragmentation demo
-module(ets_memory).
-export([test/1]).
-include_lib("stdlib/include/ms_transform.hrl").
-define(key_count, (1000 * 1000)).
-define(data_size, 512).
test(N) ->
T = ets:new(tab, [set, private]),
Keys = lists:seq(1, ?key_count),
lists:foreach(fun (K) ->
ets:insert(T, {K, data()})
end,
Keys),
M0 = memory_stats(),
lists:foreach(fun (K) ->
crypto:rand_uniform(0, 100) >= N orelse
ets:delete(T, K)
end,
Keys),
M1 = memory_stats(),
ets:select_replace(T, ets:fun2ms(fun ({K, V}) -> {K, V} end)),
M2 = memory_stats(),
ets:select_replace(T, ets:fun2ms(fun ({K, V}) -> {K, V} end)),
M3 = memory_stats(),
ets:delete(T),
#{m0 => M0,
m1 => M1,
m2 => M2,
m3 => M3,
delete => memdiff(M0, M1),
compact1 => memdiff(M0, M2),
compact2 => memdiff(M0, M3)
}.
memdiff({Bs0, Cs0}, {Bs1, Cs1}) ->
#{blocks_dn => Bs1 - Bs0,
blocks_dr => Bs1 / Bs0 - 1.0,
carriers_dn => Cs1 - Cs0,
carriers_dr => Cs1 / Cs0 - 1.0,
util0 => Bs0 / Cs0,
util1 => Bs1 / Cs1
}.
data() ->
binary_to_list(crypto:strong_rand_bytes(?data_size)).
memory_stats() ->
BsCs =
[begin
{element(2, lists:keyfind(blocks_size, 1, TypeInfo)),
element(2, lists:keyfind(carriers_size, 1, TypeInfo))
}
end
|| {instance, _, Info} <- erlang:system_info({allocator, ets_alloc}),
{Type, TypeInfo} <- Info,
case Type of
mbcs -> true;
mbcs_pool -> true;
sbcs -> true;
_ -> false
end
],
{Bs, Cs} = lists:unzip(BsCs),
{lists:sum(Bs) / (1 bsl 20), lists:sum(Cs) / (1 bsl 20)}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment