Fw: Was Mapping processes Now: ATOMS and atom_tab index

Valentin valentin@REDACTED
Wed Dec 18 20:47:45 CET 2002


 We have discovered (the hard way) that number of atoms in ERTS is limited
to
 1024*1024, which limits the number of atoms to 1,048,576. The question was
 posted recently asking how to increase this limit, but judging from the
lack
 of response, I guess, there isn't one. We have found the code where this
 table was allocated, but I do not think that the recompilation with changed
 value will do any good, as it might have side effects.

 When the space in the atom_tab index is reached,  erlang crashes with the
 bang. And quite a sizable dump.
 It might be a good idea to mention this limitation somewhere in the manual
 (hopefully in ei_x_encode_atom(...) description as well).

 Eduardo, as well as Martin before him, had a good idea (that is, if you ask
 me). It seems odd that one has to use ets, or similar mechanism to register
 a short-lived processes, if such a mechanism already exist, but cannot be
 used because it requires an atom, as an argument.

 On the other hand, I've noticed that global:register_name/2 supports string
 as registration name argument as well. I wonder, would it be wise to use
 this in a context that Eduardo was describing, by using
 global:register_name/2 and global:whereis_name/1.

 What would be the catch (other than specific syntax that has to be used in
 order to send a message?) Any performance penalty?

 Valentin.

>
> ----- Original Message -----
> From: "martin j logan" <martin@REDACTED>
> To: <eduardo@REDACTED>
> Cc: <erlang-questions@REDACTED>
> Sent: Wednesday, December 18, 2002 12:26 AM
> Subject: Re: Mapping processes
>
>
> > Eduardo,
> >    When I first started using erlang I also had this idea.  I went so
> > far as to implement it. I spent about an hour trying to figure out what
> > clever construct I had come up with in order to fool the garbage
> > collector so completely and cause such a nasty "memory leak". The thing
> > is that the first argument to register must be an atom so you must
> > convert reqID to an atom. I found out after a bit of research that atoms
> > are not garbage collected, they are stored in a table for the life of
> > the system. So in the interest of helping a fellow erlanger avoid such
> > folly as I engaged in let me say that you should not ever dynamically
> > create atoms in any situation that is not garaunteed to be finite. I
> > typically use an ets table, loop data/dict, or some such to store
> > mappings. This is coupled with some facility to remove the processes
> > when they die. In this manner you can nicely achieve the same
> > functionality.
> >
> > Cheers,
> > Martin
> >
> > On Tue, 2002-12-17 at 13:50, Vladimir Sekissov wrote:
> > > Good day,
> > >
> > > eduardo> What do you think about using register(reqId, PID) and
> > > eduardo> whereis(reqId) to
> > > eduardo> retrieve the PID so to send the response, in an async. way,
> > > eduardo> to the calling process.
> > >
> > > I think you could easily exceed the atoms table limit on long living
> > > system. Using simple dictionary of {callerPid, reqId} and trapping
> > > exit messages from callers to delete records from dictionary would be
> > > better solution. May be like this or as gen_server:
> > >
> > > create_dict() ->
> > >   spawn_link(fun dict_srv/0).
> > >
> > > remove_dict(DPid) ->
> > >   DPid ! {self(), stop},
> > >   receive
> > >     {DPid, stopped} ->
> > >       ok
> > >   end.
> > >
> > > dict_add(DPid, Pid, Reg) ->
> > >   DPid ! {self(), add, {Pid, Reg}}.
> > >
> > > dict_get(DPid, Reg) ->
> > >   DPid ! {self(), get, Reg},
> > >   receive
> > >     {DPid, {value, {Pid, _}}} ->
> > >       Pid;
> > >     {DPid, false} ->
> > >       undefined
> > >   end.
> > >
> > > dict_srv() ->
> > >   process_flag(trap_exit, true),
> > >   dict_loop([]).
> > >
> > > dict_loop(Dict) ->
> > >   receive
> > >     {_From, add, V={Pid, Reg}} ->
> > >       link(Pid),
> > >       dict_loop([V|Dict]);
> > >     {From, get, Reg} ->
> > >       From ! {self(), lists:keysearch(Reg, 2, Dict)},
> > >       dict_loop(Dict);
> > >     {'EXIT', Pid, Reson} ->
> > >       case lists:keymember(Pid, 1, Dict) of
> > > true ->
> > >   dict_loop(lists:keydelete(Pid, 1, Dict));
> > > false ->
> > >   exit(Reson)
> > >       end;
> > >     {From, stop} ->
> > >       From ! {self(), stopped},
> > >       ok
> > >   end.
> > >
> > > Best Regards,
> > > Vladimir Sekissov
> > >
> > > eduardo>
> > > eduardo> I'm thinking how to map processes with request Id so to
manage
> > > eduardo> callbacks when using ports.
> > > eduardo> What do you think about using register(reqId, PID) and
> whereis(reqId) to
> > > eduardo> retrieve the PID so to send the response, in an async. way,
to
> the calling process.
> > > eduardo>
> > > eduardo>
> > > eduardo>
> > > eduardo> Thanks,
> > > eduardo> Eduardo Figoli
> > > eduardo> INSwitch Solutions
> > > eduardo>
> > > eduardo>
> > > eduardo>
> > > eduardo>
> >
> >
>




More information about the erlang-questions mailing list