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:

https://blog.stenmans.org/theBeamBook/

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

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
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
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement