1persistent_term(3) Erlang Module Definition persistent_term(3)
2
3
4
6 persistent_term - Persistent terms.
7
9 This module is similar to ets in that it provides a storage for Erlang
10 terms that can be accessed in constant time, but with the difference
11 that persistent_term has been highly optimized for reading terms at the
12 expense of writing and updating terms. When a persistent term is
13 updated or deleted, a global garbage collection pass is run to scan all
14 processes for the deleted term, and to copy it into each process that
15 still uses it. Therefore, persistent_term is suitable for storing
16 Erlang terms that are frequently accessed but never or infrequently
17 updated.
18
19 Warning:
20 Persistent terms is an advanced feature and is not a general replace‐
21 ment for ETS tables. Before using persistent terms, make sure to fully
22 understand the consequence to system performance when updating or
23 deleting persistent terms.
24
25
26 Term lookup (using get/1), is done in constant time and without taking
27 any locks, and the term is not copied to the heap (as is the case with
28 terms stored in ETS tables).
29
30 Storing or updating a term (using put/2) is proportional to the number
31 of already created persistent terms because the hash table holding the
32 keys will be copied. In addition, the term itself will be copied.
33
34 When a (complex) term is deleted (using erase/1) or replaced by another
35 (using put/2), a global garbage collection is initiated. It works like
36 this:
37
38 * All processes in the system will be scheduled to run a scan of
39 their heaps for the term that has been deleted. While such scan is
40 relatively light-weight, if there are many processes, the system
41 can become less responsive until all process have scanned their
42 heaps.
43
44 * If the deleted term (or any part of it) is still used by a process,
45 that process will do a major (fullsweep) garbage collection and
46 copy the term into the process. However, at most two processes at a
47 time will be scheduled to do that kind of garbage collection.
48
49 Deletion of atoms and other terms that fit in one machine word is spe‐
50 cially optimized to avoid doing a global GC. It is still not recom‐
51 mended to update persistent terms with such values too frequently
52 because the hash table holding the keys is copied every time a persis‐
53 tent term is updated.
54
55 Some examples are suitable uses for persistent terms are:
56
57 * Storing of configuration data that must be easily accessible by all
58 processes.
59
60 * Storing of references for NIF resources.
61
62 * Storing of references for efficient counters.
63
64 * Storing an atom to indicate a logging level or whether debugging is
65 turned on.
66
68 The current implementation of persistent terms uses the literal alloca‐
69 tor also used for literals (constant terms) in BEAM code. By default, 1
70 GB of virtual address space is reserved for literals in BEAM code and
71 persistent terms. The amount of virtual address space reserved for lit‐
72 erals can be changed by using the +MIscs option when starting the emu‐
73 lator.
74
75 Here is an example how the reserved virtual address space for literals
76 can be raised to 2 GB (2048 MB):
77
78 erl +MIscs 2048
79
81 The runtime system will send a warning report to the error logger if
82 more than 20000 persistent terms have been created. It will look like
83 this:
84
85 More than 20000 persistent terms have been created.
86 It is recommended to avoid creating an excessive number of
87 persistent terms, as creation and deletion of persistent terms
88 will be slower as the number of persistent terms increases.
89
91 It is recommended to use keys like ?MODULE or {?MODULE,SubKey} to avoid
92 name collisions.
93
94 Prefer creating a few large persistent terms to creating many small
95 persistent terms. The execution time for storing a persistent term is
96 proportional to the number of already existing terms.
97
98 Updating a persistent term with the same value as it already has is
99 specially optimized to do nothing quickly; thus, there is no need com‐
100 pare the old and new values and avoid calling put/2 if the values are
101 equal.
102
103 When atoms or other terms that fit in one machine word are deleted, no
104 global GC is needed. Therefore, persistent terms that have atoms as
105 their values can be updated more frequently, but note that updating
106 such persistent terms is still much more expensive than reading them.
107
108 Updating or deleting a persistent term will trigger a global GC if the
109 term does not fit in one machine word. Processes will be scheduled as
110 usual, but all processes will be made runnable at once, which will make
111 the system less responsive until all process have run and scanned their
112 heaps for the deleted terms. One way to minimize the effects on respon‐
113 siveness could be to minimize the number of processes on the node
114 before updating or deleting a persistent term. It would also be wise to
115 avoid updating terms when the system is at peak load.
116
117 Avoid storing a retrieved persistent term in a process if that persis‐
118 tent term could be deleted or updated in the future. If a process holds
119 a reference to a persistent term when the term is deleted, the process
120 will be garbage collected and the term copied to process.
121
122 Avoid updating or deleting more than one persistent term at a time.
123 Each deleted term will trigger its own global GC. That means that
124 deleting N terms will make the system less responsive N times longer
125 than deleting a single persistent term. Therefore, terms that are to be
126 updated at the same time should be collected into a larger term, for
127 example, a map or a tuple.
128
130 The following example shows how lock contention for ETS tables can be
131 minimized by having one ETS table for each scheduler. The table identi‐
132 fiers for the ETS tables are stored as a single persistent term:
133
134 %% There is one ETS table for each scheduler.
135 Sid = erlang:system_info(scheduler_id),
136 Tid = element(Sid, persistent_term:get(?MODULE)),
137 ets:update_counter(Tid, Key, 1).
138
140 key() = term()
141
142 Any Erlang term.
143
144 value() = term()
145
146 Any Erlang term.
147
149 erase(Key) -> Result
150
151 Types:
152
153 Key = key()
154 Result = boolean()
155
156 Erase the name for the persistent term with key Key. The return
157 value will be true if there was a persistent term with the key
158 Key, and false if there was no persistent term associated with
159 the key.
160
161 If there existed a previous persistent term associated with key
162 Key, a global GC has been initiated when erase/1 returns. See
163 Description.
164
165 get() -> List
166
167 Types:
168
169 List = [{key(), value()}]
170
171 Retrieve the keys and values for all persistent terms. The keys
172 will be copied to the heap for the process calling get/0, but
173 the values will not.
174
175 get(Key) -> Value
176
177 Types:
178
179 Key = key()
180 Value = value()
181
182 Retrieve the value for the persistent term associated with the
183 key Key. The lookup will be made in constant time and the value
184 will not be copied to the heap of the calling process.
185
186 This function fails with a badarg exception if no term has been
187 stored with the key Key.
188
189 If the calling process holds on to the value of the persistent
190 term and the persistent term is deleted in the future, the term
191 will be copied to the process.
192
193 get(Key, Default) -> Value
194
195 Types:
196
197 Key = key()
198 Default = Value = value()
199
200 Retrieve the value for the persistent term associated with the
201 key Key. The lookup will be made in constant time and the value
202 will not be copied to the heap of the calling process.
203
204 This function returns Default if no term has been stored with
205 the key Key.
206
207 If the calling process holds on to the value of the persistent
208 term and the persistent term is deleted in the future, the term
209 will be copied to the process.
210
211 info() -> Info
212
213 Types:
214
215 Info = #{count := Count, memory := Memory}
216 Count = Memory = integer() >= 0
217
218 Return information about persistent terms in a map. The map has
219 the following keys:
220
221 count:
222 The number of persistent terms.
223
224 memory:
225 The total amount of memory (measured in bytes) used by all
226 persistent terms.
227
228 put(Key, Value) -> ok
229
230 Types:
231
232 Key = key()
233 Value = value()
234
235 Store the value Value as a persistent term and associate it with
236 the key Key.
237
238 If the value Value is equal to the value previously stored for
239 the key, put/2 will do nothing and return quickly.
240
241 If there existed a previous persistent term associated with key
242 Key, a global GC has been initiated when put/2 returns. See
243 Description.
244
245
246
247Ericsson AB erts 10.3.5.2 persistent_term(3)