Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory Leak Observed in Erlang Application

Let me put my question as simple as below. Mine is a network router software built in erlang, but at a particular scenario I am observing very high memory growth as shown by VM.

I have one process which receives binary packet from some other process from socket.

This process, parses the binary packet and passes the binary packet to a gen_server (handle_cast is called)

The gen_server again stores some information in ETS table and send the packet to the peer server.

When the peer server responds back the entry from the ETS is deleted and the gen_server responds back to the first process

Also if the first process (which sent packet to gen_server) gets timedout after 5 seconds waiting for response from gen_server , it also deletes the ETS entry in the gen_server and exits.

Now I am observing high memory growth when lots of events gets timed out (due to unavailability of peer server) and from what i have researched its the "**binary**" and "**processes_used**" given by erlang:memory command thats using most of the memory.

but the same is not true when events are processed successfully.

like image 575
Arunmu Avatar asked Dec 01 '22 08:12

Arunmu


2 Answers

The memory lost can be basically only in three places:

  1. The state of your gen_server

    • look at you state, find out if there is some big or growing stuff there
  2. Your processes mailboxes

    • see to it that there is some way to always drain unmatched messages (for gen_server handle_info callback) in normal receives a Any ->clause.

    • if the mailbox only fills up temporarily its probably because of the receiving process being too slow for the rate of messages produced. This is usually a problem for asynchronous communication. If its only temporary bursts that don't break anything this could be intended.

      • In this case you can either optimize the receiving process

      • or fix your protocol to use fewer messages

      • if you have multiple functions that receive some messages, make sure all receiving parts are being called regularly. Dont forget the Any -> clauses.

    • Be aware that while you are processing in a gen_servers callback no messages will be received, so if you need more time in a callback that would be necessary asyncronous messages might pile up (e.g. random message arrival + fixed processing time builds a unbounded growing queue, for details see Queueing theory

  3. In your ETS table

    • maybe the information in the ETS is not be completely removed? Forgot to remove something in certain cases?
like image 174
Peer Stritzinger Avatar answered Jan 31 '23 22:01

Peer Stritzinger


trigger GC by hand and see what happens with memory.

[garbage_collect(Pid) || Pid <- processes()] 
like image 42
user425720 Avatar answered Jan 31 '23 20:01

user425720