dan-cooke

dan-cooke

Need help understanding memory allocations in this code

Hi all,

I’m just learning elixir for fun , and I would love to understand a little bit more about the memory allocations that are made during the following code snippet taken from the Mix OTP tutorial:

defp loop_acceptor(socket) do
  {:ok, client} = :gen_tcp.accept(socket)
  {:ok, pid} = Task.Supervisor.start_child(KVServer.TaskSupervisor, fn -> serve(client) end)
  :ok = :gen_tcp.controlling_process(client, pid)
  loop_acceptor(socket)
end

Heres what I am thinking so far:

  1. loop_acceptor function is called and socket is placed onto the stack for this function call
  2. :gen_tcp.accept(socket) is called which creates a socket resource called client, this is currently owned by the process that called loop_acceptor
  3. Task.Supervisor.start_child is called, the anon function creates a closure which captures the serve function and the client.

Thats where I get stuck.

  1. Does this closure which runs in a new process result in the variables it captures being “copied” into the new process heap/stack?
  2. If so.. how is it possible to “copy” a resource like a socket without creating multiple OS sockets for the same connection?
  3. As the serve function belongs to the surrounding KVServer module does this mean that the supervised task gets a copy of the KVServer module too?

If anyone has any good documentation to learn more about BEAM memory, or perhaps some tips on how I can debug these allocations myself.

I’m very green with BEAM

Any help is greatly appreciated, thanks!

Marked As Solved

al2o3cr

al2o3cr

#1: yes, the closure captures its environment. Rebinding client after the call to Task.Supervisor.start_child won’t change the value the child process sees.

#2: the thing that’s returned from :gen_tcp.accept is usually a “port”; short short version it’s a way to name the thing that’s actually holding the OS socket. Calling controlling_process tells the port that it should send messages etc to the newly-started task instead of the process that originally called :gen_tcp.accept.

#3: there’s no state attached to the module KVServer, so asking whether there’s a second “copy” of it isn’t particularly meaningful. There’s some very tricky corner-cases around hot-code reloading that make calling serve(client) different from calling KVServer.serve(client) (even from inside a function defined in KVServer!) but most people will never encounter them.

Also Liked

derek-zhou

derek-zhou

The authoritative source of BEAM internal is the Beam book:

It really depends on how deep you want to go. From the 10,000 foot above, you can consider all values are allocated on the per-process heap and are immutable. So there will not be cyclic references, GC is straight forward, and closure is easy to implement.

Of cause there are exceptions, but the native code hide the ugly parts and maintain the happy illusion.

Where Next?

Popular in Questions Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: <h1>Create Post</h1> <%= ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

We're in Beta

About us Mission Statement