I have in my application a few GenServers caching data which could eventually lead to out-of-memory errors.
Is there a low memory signal I could handle from my GenServer to let them free some memory?
How would you handle such a case?
I have in my application a few GenServers caching data which could eventually lead to out-of-memory errors.
Is there a low memory signal I could handle from my GenServer to let them free some memory?
How would you handle such a case?
If you want to hint GC run for given process then you can hibernate it when it is not doing stuff
Returning
{:reply, reply, new_state, :hibernate}
is similar to{:reply, reply, new_state}
except the process is hibernated and will continue the loop once a message is in its message queue. However, if a message is already in the message queue, the process will continue the loop immediately. Hibernating aGenServer
causes garbage collection and leaves a continuous heap that minimises the memory used by the process.
Thanks!
I think I will make my GenServer periodically (with Process.send_after
) check the BEAM memory usage and if required, flush the GenServer’s state (and maybe force a GC)
@hauleth thanks for the idea, but I don’t this fit my need. I want the GenServer to be always responsive, and just GarbageCollecting won’t be enough (its state takes a lot of memory)
After reading :os_mon
and :memsup
documentation, it’s even better than what I thought!
We can register alarm handlers that will be triggered when a custom memory threshold is reached. I’ll post my code here when I get it working.
The only problem is that the minimum interval for checking memory seems to be one minute.
disksup
(also part of os_mon
) supports smaller time interval since recently, I guess a patch to have the same feature for memsup
would make sense.
If you need to check more often then you can use memsup:get_system_memory_data/0
(example here).