Skip to main content

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.

References