This question is applicable to both Elixir and Erlang, since it is a question about the OTP feature ‘Hibernation’.
I am currently working on a small library to create ‘persistent GenServers’, which allow storing the state of a GenServer to disk when they are not being used, and start them up later when they are required again, because I’ve come across multiple situations where I wanted such an abstraction (and ended up implementing an unfinished, bug-ridden implementation of half of it).
At first I wanted to call this persisting/unpersisting ‘hibernating’ a process, but I quickly realized that the term hibernation is already overloaded in OTP. See for instance Process.hibernate/3, :erlang.hibernate/3 and the
:hibernate option that can be passed to a GenServer on startup to trigger the same after a timeout:
Puts the calling process into a wait state where its memory allocation has been reduced as much as possible. This is useful if the process does not expect to receive any messages soon.
(The documentation then continues on to describe preconditions and postconditions to keep in mind when using it.)
Now while this explains what it does it is not yet clear to me when exactly it is useful: A process that is hibernating still takes up space in RAM. It feels like this strange half-measure:
- If the process is short-lived, no reason to hibernate.
- If the process is long-lived but is in use all the time, no reason to hibernate.
- If the process is long-lived but probably won’t be used for a long time, then why keep it around in memory at all? Chances are that requiring the process to stick around for a long time that the data it contains isn’t ephemeral but needs to survive external failures (like node restarts) as well.
It’s highly possible that my reasoning is flawed or missing something. Please help !
Why was the ‘Hibernation’ functionality created in the first place? Were there certain performance issues that the OTP team wanted to address with it? In what situation(s) is process hibernation used in practice?