forked from happi/theBeamBook
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
10702 lines (10363 loc) · 804 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.9">
<title>The Erlang Runtime System</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
/* Default font. */
body {
font-family: Georgia,serif;
}
/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
font-family: Arial,Helvetica,sans-serif;
}
body {
margin: 1em 5% 1em 5%;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: fuchsia;
}
em {
font-style: italic;
color: navy;
}
strong {
font-weight: bold;
color: #083194;
}
h1, h2, h3, h4, h5, h6 {
color: #527bbd;
margin-top: 1.2em;
margin-bottom: 0.5em;
line-height: 1.3;
}
h1, h2, h3 {
border-bottom: 2px solid silver;
}
h2 {
padding-top: 0.5em;
}
h3 {
float: left;
}
h3 + * {
clear: left;
}
h5 {
font-size: 1.0em;
}
div.sectionbody {
margin-left: 0;
}
hr {
border: 1px solid silver;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
ul > li { color: #aaa; }
ul > li > * { color: black; }
.monospaced, code, pre {
font-family: "Courier New", Courier, monospace;
font-size: inherit;
color: navy;
padding: 0;
margin: 0;
}
pre {
white-space: pre-wrap;
}
#author {
color: #527bbd;
font-weight: bold;
font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}
#footer {
font-size: small;
border-top: 2px solid silver;
padding-top: 0.5em;
margin-top: 4.0em;
}
#footer-text {
float: left;
padding-bottom: 0.5em;
}
#footer-badges {
float: right;
padding-bottom: 0.5em;
}
#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.0em;
margin-bottom: 2.0em;
margin-right: 10%;
color: #606060;
}
div.content { /* Block element content. */
padding: 0;
}
/* Block element titles. */
div.title, caption.title {
color: #527bbd;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid #dddddd;
border-left: 4px solid #f0f0f0;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid #dddddd;
border-left: 5px solid #f0f0f0;
background: #f8f8f8;
padding: 0.5em;
}
div.quoteblock, div.verseblock {
padding-left: 1.0em;
margin-left: 1.0em;
margin-right: 10%;
border-left: 5px solid #f0f0f0;
color: #888;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock > pre.content {
font-family: inherit;
font-size: inherit;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #527bbd;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 3px solid #dddddd;
}
div.exampleblock > div.content {
border-left: 3px solid #dddddd;
padding-left: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: navy;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: navy;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
.footnote, .footnoteref {
font-size: 0.8em;
}
span.footnote, span.footnoteref {
vertical-align: super;
}
#footnotes {
margin: 20px 0 20px 0;
padding: 7px 0 0 0;
}
#footnotes div.footnote {
margin: 0 0 5px 0;
}
#footnotes hr {
border: none;
border-top: 1px solid silver;
height: 1px;
text-align: left;
margin-left: 0;
width: 20%;
min-width: 100px;
}
div.colist td {
padding-right: 0.5em;
padding-bottom: 0.3em;
vertical-align: top;
}
div.colist td img {
margin-top: 0.3em;
}
@media print {
#footer-badges { display: none; }
}
#toc {
margin-bottom: 2.5em;
}
#toctitle {
color: #527bbd;
font-size: 1.1em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
margin-top: 0;
margin-bottom: 0;
}
div.toclevel2 {
margin-left: 2em;
font-size: 0.9em;
}
div.toclevel3 {
margin-left: 4em;
font-size: 0.9em;
}
div.toclevel4 {
margin-left: 6em;
font-size: 0.9em;
}
span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }
span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }
span.big { font-size: 2em; }
span.small { font-size: 0.6em; }
span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }
div.unbreakable { page-break-inside: avoid; }
/*
* xhtml11 specific
*
* */
div.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.tableblock > table {
border: 3px solid #527bbd;
}
thead, p.table.header {
font-weight: bold;
color: #527bbd;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
/*
* html5 specific
*
* */
table.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
thead, p.tableblock.header {
font-weight: bold;
color: #527bbd;
}
p.tableblock {
margin-top: 0;
}
table.tableblock {
border-width: 3px;
border-spacing: 0px;
border-style: solid;
border-color: #527bbd;
border-collapse: collapse;
}
th.tableblock, td.tableblock {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #527bbd;
}
table.tableblock.frame-topbot {
border-left-style: hidden;
border-right-style: hidden;
}
table.tableblock.frame-sides {
border-top-style: hidden;
border-bottom-style: hidden;
}
table.tableblock.frame-none {
border-style: hidden;
}
th.tableblock.halign-left, td.tableblock.halign-left {
text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
text-align: right;
}
th.tableblock.valign-top, td.tableblock.valign-top {
vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
vertical-align: bottom;
}
/*
* manpage specific
*
* */
body.manpage h1 {
padding-top: 0.5em;
padding-bottom: 0.5em;
border-top: 2px solid silver;
border-bottom: 2px solid silver;
}
body.manpage h2 {
border-style: none;
}
body.manpage div.sectionbody {
margin-left: 3em;
}
@media print {
body.manpage div#toc { display: none; }
}
@media screen {
body {
max-width: 50em; /* approximately 80 characters wide */
margin-left: 16em;
}
#toc {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 13em;
padding: 0.5em;
padding-bottom: 1.5em;
margin: 0;
overflow: auto;
border-right: 3px solid #f8f8f8;
background-color: white;
}
#toc .toclevel1 {
margin-top: 0.5em;
}
#toc .toclevel2 {
margin-top: 0.25em;
display: list-item;
color: #aaaaaa;
}
#toctitle {
margin-top: 0.5em;
}
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = { // Namespace.
/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////
/* Author: Mihai Bazon, September 2002
* http://students.infoiasi.ro/~mishoo
*
* Table Of Content generator
* Version: 0.4
*
* Feel free to use this script under the terms of the GNU General Public
* License, as long as you do not remove or alter this notice.
*/
/* modified by Troy D. Hanson, September 2006. License: GPL */
/* modified by Stuart Rackham, 2006, 2009. License: GPL */
// toclevels = 1..4.
toc: function (toclevels) {
function getText(el) {
var text = "";
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
text += i.data;
else if (i.firstChild != null)
text += getText(i);
}
return text;
}
function TocEntry(el, text, toclevel) {
this.element = el;
this.text = text;
this.toclevel = toclevel;
}
function tocEntries(el, toclevels) {
var result = new Array;
var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
// Function that scans the DOM tree for header elements (the DOM2
// nodeIterator API would be a better technique but not supported by all
// browsers).
var iterate = function (el) {
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
var mo = re.exec(i.tagName);
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
}
iterate(i);
}
}
}
iterate(el);
return result;
}
var toc = document.getElementById("toc");
if (!toc) {
return;
}
// Delete existing TOC entries in case we're reloading the TOC.
var tocEntriesToRemove = [];
var i;
for (i = 0; i < toc.childNodes.length; i++) {
var entry = toc.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div'
&& entry.getAttribute("class")
&& entry.getAttribute("class").match(/^toclevel/))
tocEntriesToRemove.push(entry);
}
for (i = 0; i < tocEntriesToRemove.length; i++) {
toc.removeChild(tocEntriesToRemove[i]);
}
// Rebuild TOC entries.
var entries = tocEntries(document.getElementById("content"), toclevels);
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (entry.element.id == "")
entry.element.id = "_toc_" + i;
var a = document.createElement("a");
a.href = "#" + entry.element.id;
a.appendChild(document.createTextNode(entry.text));
var div = document.createElement("div");
div.appendChild(a);
div.className = "toclevel" + entry.toclevel;
toc.appendChild(div);
}
if (entries.length == 0)
toc.parentNode.removeChild(toc);
},
/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////
/* Based on footnote generation code from:
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
*/
footnotes: function () {
// Delete existing footnote entries in case we're reloading the footnodes.
var i;
var noteholder = document.getElementById("footnotes");
if (!noteholder) {
return;
}
var entriesToRemove = [];
for (i = 0; i < noteholder.childNodes.length; i++) {
var entry = noteholder.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
entriesToRemove.push(entry);
}
for (i = 0; i < entriesToRemove.length; i++) {
noteholder.removeChild(entriesToRemove[i]);
}
// Rebuild footnote entries.
var cont = document.getElementById("content");
var spans = cont.getElementsByTagName("span");
var refs = {};
var n = 0;
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnote") {
n++;
var note = spans[i].getAttribute("data-note");
if (!note) {
// Use [\s\S] in place of . so multi-line matches work.
// Because JavaScript has no s (dotall) regex flag.
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
spans[i].innerHTML =
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
spans[i].setAttribute("data-note", note);
}
noteholder.innerHTML +=
"<div class='footnote' id='_footnote_" + n + "'>" +
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
n + "</a>. " + note + "</div>";
var id =spans[i].getAttribute("id");
if (id != null) refs["#"+id] = n;
}
}
if (n == 0)
noteholder.parentNode.removeChild(noteholder);
else {
// Process footnoterefs.
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnoteref") {
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
href = href.match(/#.*/)[0]; // Because IE return full URL.
n = refs[href];
spans[i].innerHTML =
"[<a href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
}
}
}
},
install: function(toclevels) {
var timerId;
function reinstall() {
asciidoc.footnotes();
if (toclevels) {
asciidoc.toc(toclevels);
}
}
function reinstallAndRemoveTimer() {
clearInterval(timerId);
reinstall();
}
timerId = setInterval(reinstall, 500);
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
else
window.onload = reinstallAndRemoveTimer;
}
}
asciidoc.install(2);
/*]]>*/
</script>
</head>
<body class="book">
<div id="header">
<h1>The Erlang Runtime System</h1>
<div id="toc">
<div id="toctitle">Table of Contents</div>
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_preface">Preface</h2>
<div class="sectionbody">
<div class="paragraph"><p>This book is not about how to write correct and
beautiful code, I am assuming that you already know how to do
that. This book isn’t really about profiling and performance tuning
either. Although, there is a chapter in this book on tracing and
profiling which can help you find bottlenecks and unnecessary usage of
resources. There also is a chapter on performance tuning.</p></div>
<div class="paragraph"><p>These two chapters are the last chapters in the book, and the whole
book is building up to those chapters, but the real goal with this
book is to give you all the information, all the gory details, that
you need in order to really understand the performance of your Erlang
application.</p></div>
<div class="sect2">
<h3 id="who_is_this_book_for">About this book</h3>
<div class="paragraph"><p>For anyone who: Want to tune an Erlang installation. Want to know how
to debug VM crashes. Want to improve performance of Erlang
applications. Want to understand how Erlang really works. Want to
learn how to build your own runtime environment.</p></div>
<div class="paragraph"><p>If you want to debug the VM If you want to extend the VM If you want
to do performance tweaking—jump to the last chapter … but to really
understand that chapter you need to read the book.</p></div>
</div>
<div class="sect2">
<h3 id="_how_to_read_this_book">How to read this book</h3>
<div class="paragraph"><p>The Erlang RunTime System (ERTS) is a complex system with many
interdependent components. It is written in a very portable way so
that it can run on anything from a gum-stick computer to the largest
multicore system with terabytes of memory. In order to be able to
optimize the performance of such a system for your application, you
need to not only know your application, but you also need to have a
thorough understanding of ERTS itself.</p></div>
<div class="paragraph"><p>With this knowledge of how ERTS works you will be able to understand
how your application behaves when running on ERTS, and you will also
be able to find and fix problems with the performance of your application.
In the second part of this book we will go through how you successfully
run, monitor and scale your ERTS application.</p></div>
<div class="paragraph"><p>You don’t need to be an Erlang programmer to read this book, but you
will need some basic understanding of what Erlang is. This following
section will give you some Erlang background.</p></div>
</div>
<div class="sect2">
<h3 id="_erlang">Erlang</h3>
<div class="paragraph"><p>In this section we will look at some basic Erlang concepts that
are vital to understanding the rest of the book.</p></div>
<div class="paragraph"><p>Erlang has been called, especially by one of Erlang’s creators Joe
Armstrong, a concurrency oriented language. Concurrency is definitely
at the heart of Erlang, and to be able to understand how an Erlang
system works you need to understand the concurrency model of Erlang.</p></div>
<div class="paragraph"><p>First of all we need to make a distinction between <em>concurrency</em> and
<em>parallelism</em>. In this book <em>concurrency</em> is the concept of having
two or more processes that <strong>can</strong> execute independently of each other,
this can be done by first executing one process then the other or by
interleaving the execution, or by executing the processes in
parallel. With <em>parallel</em> executions we mean that the processes
actually execute at the exact same time by using several physical
execution units. Parallelism can be achieved on different levels.
Through multiple execution units in the execution pipeline in one core,
in several cores on one CPU, by several CPUs in one machine or through
several machines.</p></div>
<div class="paragraph"><p>Erlang uses processes to achieve concurrency. Conceptually Erlang
processes are similar to most OS processes, they execute in parallel
and can communicate through signals. In practices there is a huge
difference in that Erlang processes are much more lightweight than
most OS processes. Many other concurrent programming languages call
their equivalent to Erlang processes <em>agents</em>.</p></div>
<div class="paragraph"><p>Erlang achieves concurrency by interleaving the execution of processes
on the Erlang virtual machine, the BEAM. On multi-core processor the
BEAM can also achieve parallelism by running one scheduler per core and
executing one Erlang process per scheduler. The designer of an Erlang
system can achieve further parallelism by distributing the system on
several computers.</p></div>
<div class="paragraph"><p>A typical Erlang system (a server or service built in Erlang) consists
of a number of Erlang <em>applications</em>, corresponding to a directory on disk.
Each application is made up of several Erlang <em>modules</em> corresponding to
files in the directory. Each module contains a number of <em>functions</em> and
each function is made up of <em>expressions</em>.</p></div>
<div class="paragraph"><p>Since Erlang is a functional language it has no statements,
only expressions. Erlang expressions can be combined to an Erlang
function. A function takes a number of arguments and returns a
value. In <a href="#erlang_code_examples">[erlang_code_examples]</a> we can see some examples of
Erlang expressions and functions.</p></div>
<div class="listingblock">
<a id="erlang_code_examples"></a>
<div class="title">Erlang Code Examples</div>
<div class="content"><!-- Generator: GNU source-highlight 3.1.7
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-style: italic"><span style="color: #9A1900">%% Some Erlang expressions:</span></span>
<span style="color: #000080">true</span><span style="color: #990000">.</span>
<span style="color: #993399">1</span><span style="color: #990000">+</span><span style="color: #993399">1</span><span style="color: #990000">.</span>
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> (<span style="color: #009900">X</span> <span style="color: #990000">></span> <span style="color: #009900">Y</span>) <span style="color: #990000">-></span> <span style="color: #009900">X</span>; <span style="color: #000080">true</span> <span style="color: #990000">-></span> <span style="color: #009900">Y</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span><span style="color: #990000">.</span>
<span style="font-style: italic"><span style="color: #9A1900">%% An Erlang function:</span></span>
<span style="font-weight: bold"><span style="color: #000000">max</span></span>(<span style="color: #009900">X</span>, <span style="color: #009900">Y</span>) <span style="color: #990000">-></span>
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> (<span style="color: #009900">X</span> <span style="color: #990000">></span> <span style="color: #009900">Y</span>) <span style="color: #990000">-></span> <span style="color: #009900">X</span>;
<span style="color: #000080">true</span> <span style="color: #990000">-></span> <span style="color: #009900">Y</span>
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span><span style="color: #990000">.</span></tt></pre></div></div>
<div class="paragraph"><p>Erlang has a number of <em>built in functions</em> (or <em>BIFs</em>) which are
implemented by the VM. This is either for efficiency reasons, like the
implementation of <span class="monospaced">lists:append</span> (which could be implemented in
Erlang). It could also be to provide some low level functionality
which would be hard or impossible to implement in Erlang itself, like
<span class="monospaced">list_to_atom</span>.</p></div>
<div class="paragraph"><p>Since Erlang/OTP R13B03 you can also provide your own functions
implemented in C by using the <em>Native Implemented Functions</em> (<em>NIF</em>)
interface.</p></div>
</div>
<div class="sect2">
<h3 id="_acknowledgments">Acknowledgments</h3>
<div class="paragraph"><p>A big thank you to everyone who has contributed in some way by checking in
something:</p></div>
<div class="literalblock">
<div class="content monospaced">
<pre>Roberto Aloi
Alexandre Rodrigues
Ken Causey
Michał Piotrowski
Anthony Molinaro
Benjamin Tan Wei Hao
Cameron Price
Jan Lehnardt
PlatinumThinker
Yago Riveiro
Yoshihiro TANAKA</pre>
</div></div>
</div>
</div>
</div>
<h1 id="P-ERTS">Understanding ERTS</h1>
<div class="sect1">
<h2 id="introduction">Introducing the Erlang Runtime System</h2>
<div class="sectionbody">
<div class="paragraph"><p>The Erlang RunTime System (ERTS) is a complex system with many interdependent
components. It is written in a very portable way so that it can run on
anything from a gum stick computer to the largest multicore system
with terabytes of memory. In order to be able to optimize the
performance of such a system for your application, you need to not
only know your application, but you also need to have a thorough
understanding of ERTS itself.</p></div>
<div class="sect2">
<h3 id="_erts_and_the_erlang_runtime_system">ERTS and the Erlang Runtime System</h3>
<div class="paragraph"><p>There is a difference between any Erlang Runtime System and a specific implementation of an Erlang Runtime
System. "Erlang/OTP" by Ericsson is the de facto standard
implementation of Erlang and the Erlang Runtime System. In this book I
will refer to this implementation as <em>ERTS</em> or spelled out <em>Erlang
RunTime System</em> with a capital T. (See <a href="#ERTS">[ERTS]</a> for a definition of
OTP).</p></div>
<div class="paragraph"><p>There is no official definition of what an Erlang Runtime System is,
or what an Erlang Virtual Machine is. You could sort of imagine what
such an ideal Platonic system would look like by taking ERTS and
removing all the implementation specific details. This is
unfortunately a circular definition, since you need to know the
general definition to be able to identify an implementation specific
detail. In the Erlang world we are usually too pragmatic to worry about
this.</p></div>
<div class="paragraph"><p>I will try to use the term <em>Erlang Runtime System</em> to refer to the
general idea of any Erlang Runtime System as opposed to the specific
implementation by Ericsson which I’ll call the Erlang RunTime System
or usually just ERTS.</p></div>
<div class="paragraph"><p><strong>Note</strong> This book is mostly a book about ERTS in particular and only to
a small extent about any general Erlang Runtime System. If you assume
that I talk about the Ericsson implementation unless I clearly state
that I am talking about a general principle you will probably be
right.</p></div>
</div>
<div class="sect2">
<h3 id="_how_to_read_this_book_2">How to read this book</h3>
<div class="paragraph"><p>In <a href="#P-Running">[P-Running]</a> of this book I will show you how to tune the
runtime system for your application and how to profile and debug
your application and the runtime system. In order to really know
how to tune the system you also need to know the system. In
<a href="#P-ERTS">[P-ERTS]</a> of this book you will get a deep understanding of
how the runtime system works.</p></div>
<div class="paragraph"><p>In the following chapters of <a href="#P-ERTS">[P-ERTS]</a> I will try to explain each
component of the system by itself, in a separate chapter for each of
the major component. You should be able to read any one of these
chapters without having a full understanding of how the other
components are implemented, but you will need a basic understanding of
what each component is. The rest of this introductory chapter should
give you enough basic understanding and vocabulary to be able to jump
between the rest of the chapters in part one in any order you like.</p></div>
<div class="paragraph"><p>However, if you have the time I strongly recommend reading the book in
order the first time. Words that are specific to Erlang and ERTS or
used in a specific way in this book are usually explained at their
first occurrence. Then, when you know the vocabulary, you can come
back and use Part I as a reference whenever you have a problem with a
particular component.</p></div>
</div>
<div class="sect2">
<h3 id="ERTS">ERTS</h3>
<div class="paragraph"><p>In this section I will give a basic overview of the main components of
ERTS and some vocabulary needed to understand the more
detailed descriptions of each component in the following chapters.</p></div>
<div class="sect3">
<h4 id="_the_erlang_node_erts">The Erlang Node (ERTS)</h4>
<div class="paragraph"><p>An Erlang node is a running instance of ERTS (or
possibly another implementation of Erlang (see
<a href="#Other_Erlang_Implementations">[Other_Erlang_Implementations]</a>)).
In OO terminology one could say that an Erlang node is an object
of the Erlang Runtime System class.</p></div>
<div class="paragraph"><p>All execution of Erlang code is done within a node. An erlang node
corresponds to an OS process and you can have several Erlang nodes
running on one machine.</p></div>
<div class="paragraph"><p>Your Erlang program (or application) will run in one or more Erlang
nodes, and the performance of your program will depend not only on
your application code but also on all the layers below your code
in the <em>Erlang solution stack</em>. In particular if you are running
your code on top of ERTS you will need to know the components of
the <em>ERTS Stack</em>.</p></div>
<div class="paragraph"><p>In <a href="#the_erts_stack">[the_erts_stack]</a> you can see the ERTS Stack illustrated with
two Erlang nodes running on one machine.</p></div>
<div class="paragraph"><p>At the bottom of the stack there is the hardware you are running
on. The easiest way to improve the performance of your app is probably
to run it on better hardware. If economical or physical constraints
won’t let you upgrade your hardware you can start exploring higher
levels of the stack. The two most important choices for your hardware
is whether it is multicore and whether it is 32-bit or 64-bit. You
need different builds of ERTS depending on whether you want to use
multicore or not and whether you want to use 32-bit or 64-bit. (See
<a href="#CH-BuildingERTS">[CH-BuildingERTS]</a> for information on how to build different