[erlang-questions] UDP concurrent server

Fred Hebert mononcqc@REDACTED
Wed Dec 9 15:27:57 CET 2015

On 12/09, Bogdan Andu wrote:
>handle_info({udp, Socket, Host, Port, Bin}, State)  ->
>    {noreply, State};
>In a few minutes the memory allocated to binary increases to ~ 500MB
>by running the command:
>fmpeg -f lavfi -i aevalsrc="sin(40*2*PI*t)" -ar 8000 -f mulaw -f rtp rtp://
>It seems that the Bins are accumulated in the process memory area, an never
>are deallocated
>unless the process is killed, which is not an option.

So there's two ways about that. If the size of each binary is > 64 bits, 
then the binary is moved to a global shared heap, and is only collected 
once no process at all has a reference to it anymore.

This takes a few forms:

1. either the process receiving the data and passing it on holds on to 
it inadvertently by not garbage-collecting
2. the processes the messages would be forwarded to are keeping a copy.
3. the process isn't keeping up

In this case, it would be weird for it to be blameable on 2) and 3) 
since the snippet above does not forward data, and because "not keeping 
up" would affect both forms the same (the following one, I mean:)

>If I change the clause to:
>handle_info({udp1, Socket, Host, Port, Bin}, State) ->
>So as long as the process receives the packet, this is accumulated in
>binary memory are
>and never deallocated.

So the interesting bit there is are you sure the memory isn't just going 
elsewhere? That you're doing nothing with the process? Not matching on 
the message does not mean the message isn't read. Any receive operation 
(or most of them, as far as I can tell) work by taking the messages in 
the mailbox, copying them to the process heap, potentially running a GC, 
and then getting the message.

Simply not matching the message does not take it out of the mailbox; in 
fact I would expect bigger leaks with that clause, unless you have a 
second one that broadly matches on all messages and discards them.

Then the problem would point at being about what you do with the 

The thing I would check is:
a) are you keeping more references than you think in what you do, or is 

>handle_info({udp, Socket, Host, Port, Bin}, State)  ->
>    {noreply, State};

really the full clause?

Another option can be to return {noreply, State, hibernate} from time to 
time, which will force a full GC and recompaction of the process memory.  
If the memory isn't shed away after that, then you know it's being 
either still referenced by the process, or has another process 
referencing it.


More information about the erlang-questions mailing list