试图找到有关细节的文档,我没有发现很多东西:
对我来说,这留下了许多不清楚的事情.
原子字值是否始终相同,与序列模块加载到运行时实例无关?如果模块A和B都定义/引用一些原子,那么原子的值会在会话之间发生变化,这取决于是先加载A还是B?
当匹配模块内的原子时,是否存在一些"原子文字到原子值"的分辨率?模块是否有一些自己的模块本地原子值查找表,它在模块的加载时填充?
在2个erlang运行时实例相互通信的分布式场景中.是否有一些"sync-atom-tables"动作正在进行?或者将原子序列化为字符串文字,而不是单词?
Gre*_*reg 11
Atom只是VM维护的ID.ID的表示是底层架构的机器整数,例如32位系统上的4个字节和64位系统上的8个字节.请参阅LYSE书中的用法.
同一个正在运行的VM中的同一个原子始终映射到相同的ID(整数).例如以下元组:
{apple, pear, cherry, apple}
Run Code Online (Sandbox Code Playgroud)
可以在实际的Erlang内存中存储为以下元组:
{1, 2, 3, 1}
Run Code Online (Sandbox Code Playgroud)
所有原子都存储在一个永远不会被垃圾收集的大表中,即一旦在正在运行的VM中创建一个原子,它就会停留在表中,直到VM关闭为止.
回答你的问题:
1.不会.原子的ID会在VM运行之间发生变化.如果关闭VM并重新加载元组,则系统最终可能会显示以下ID:
{50, 51, 52, 50}
Run Code Online (Sandbox Code Playgroud)
取决于在加载之前已创建的其他原子.原子只与VM一样长.
2.不.每个VM只有一个原子表.加载模块时,模块中的所有文字原子都映射到它们的ID.如果该表中尚不存在特定原子,则将其插入并保持不变直到VM重新启动.
3.没有原子的表是每个VM,它们是分开的.考虑两个VM同时启动但彼此不了解的情况.在每个VM中创建的原子可能在表中具有不同的ID.如果在某个时间点,一个节点了解另一个节点,则不同的原子将具有不同的ID.它们不容易同步或合并.但原子不仅仅是作为文本表示发送到另一个节点.它们被"压缩"为一种缓存形式,并在标题中一起发送.请参阅通信协议说明中的分发标头.基本上,标题包含稍后使用的原子及其ID和文本表示.然后,每个术语通过标头中指定的ID引用atom,而不是每次都传递相同的文本.