问题描述
我有汇总事件的genserver:
def init(opts) do
cache = :ets.new(:events_cache,[:set])
{:ok,cache}
end
def handle_info(:autoflush,cache) do
Logger.debug(fn -> "#{:ets.info(cache)[:size]} events was aggregated. Sending to transport..." end)
Events.emit(:ets.tab2list(cache))
Process.send_after(self(),:autoflush,@flush_after)
{:noreply,:ets.new(:events_cache,[:set])}
end
def handle_cast({:add_event,event},cache) do
:ets.insert(cache,{event})
{:noreply,cache}
end
在init
中,创建ets表。在cast
中添加值,并将数据刷新到info
中的外部调用中,以清理ets表的内存(我认为)。
问题:
- 此实现是否容易发生内存泄漏?是否会收集旧的ets表垃圾?
- 除了问题:这个实现看起来是否理智?
解决方法
在创建不带注册名称的ETS表时(选中选项named_table
),将使用引用创建表。不管您创建了多少个,旧的文件仍然存在,是的,如果不删除旧的文件,则会造成内存泄漏。
避免这种情况的一种方法是使用named_table
选项。如果存在上一个表,这将导致崩溃。您可以使用catch
或在try-catch块中创建表。