ets table 重新创建同名后会释放内存吗?
Will ets table release memory after recreating with the same name?
我有聚合事件的 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 table。在cast
中添加值并在info
中将数据刷新到外部调用清理ets的内存table(如我所想)。
问题:
- 这个实现容易出现内存泄漏吗?旧的 ets table 垃圾被收集了吗?
- 旁白问题:这个实现看起来很正常吗?
当您创建没有注册名称的 ETS table(选中选项 named_table
)时,会创建带有引用的 table。无论你创建多少,旧的仍然在那里,是的,如果你不删除旧的,你就会内存泄漏。
避免这种情况的一种方法是使用 named_table
选项。如果之前的 table 存在,这将崩溃。您可以将 table 的创建与 catch
或放在 try-catch 块中。
我有聚合事件的 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 table。在cast
中添加值并在info
中将数据刷新到外部调用清理ets的内存table(如我所想)。
问题:
- 这个实现容易出现内存泄漏吗?旧的 ets table 垃圾被收集了吗?
- 旁白问题:这个实现看起来很正常吗?
当您创建没有注册名称的 ETS table(选中选项 named_table
)时,会创建带有引用的 table。无论你创建多少,旧的仍然在那里,是的,如果你不删除旧的,你就会内存泄漏。
避免这种情况的一种方法是使用 named_table
选项。如果之前的 table 存在,这将崩溃。您可以将 table 的创建与 catch
或放在 try-catch 块中。