Improper Resource Allocation - Memory Leak
Need
To avoid exhausting system resources due to memory leaks
Context
- Usage of Elixir 1.12 for building scalable and concurrent applications
- Usage of Phoenix Framework 1.6 for web development
Description
Non compliant code
defmodule MemoryLeak do
def leak_memory do
spawn(fn ->
Process.flag(:trap_exit, true)
accumulate([])
end)
end
defp accumulate(list) do
new_list = [0 | list]
accumulate(new_list)
end
end
The following code demonstrates a memory leak situation in Elixir. A process is spawned that starts a large data structure (a list), which is continually appended with elements. However, these elements are never released and accumulate over time, leading to increased memory usage.
Steps
- Monitor your processes and identify those that continue to consume memory over time
- Limit the lifetime of processes that create large data structures
- Consider making use of Elixir's garbage collection features to manually trigger garbage collection in certain situations
Compliant code
defmodule MemoryLeak do
def leak_memory do
spawn(fn ->
Process.flag(:trap_exit, true)
accumulate([])
Process.sleep(10000)
:ok
end)
end
defp accumulate(list) when length(list) < 1_000_000 do
new_list = [0 | list]
accumulate(new_list)
end
defp accumulate(_list), do: :ok
end
In this solution, the process is set to terminate after a certain period of time, ensuring that the large data structure it has created is released from memory.