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