{"id":47447,"date":"2015-10-15T15:27:30","date_gmt":"2015-10-15T12:27:30","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=47447"},"modified":"2019-11-27T18:09:36","modified_gmt":"2019-11-27T15:09:36","slug":"golang-internals-part-6-bootstrapping-and-memory-allocator-initialization","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/","title":{"rendered":"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/11\/golang.sh-600x600-e1444911557771.png\" alt=\"Go Gopher\" height=\"160\" class=\"size-full wp-image-47448\" align=\"right\" \/><\/p>\n<p><center><small>All parts: <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-1-main-concepts-and-project-structure\/\">Part 1<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-2-diving-into-the-go-compiler\/\">Part 2<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\">Part 3<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/\">Part 4<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-5-the-runtime-bootstrap-process\/\">Part 5<\/a> | <strong>Part 6<\/strong><\/small><\/center><\/p>\n<p>&nbsp;<\/p>\n<p>This post is the continuation of our Golang Internals series. It explores the bootstrapping process, which is key to understanding the Go runtime, in more detail. In this part, we will run through the second portion of the starting sequence, learn how arguments are initialized, what functions are called, etc.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#The_starting_sequence\" >The starting sequence<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Analyzing_arguments\" >Analyzing arguments<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#The_runtimeosinit_and_runtimeschedinit_functions\" >The runtime.osinit and runtime.schedinit functions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Initializing_traceback\" >Initializing traceback<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Verifying_linker_symbols\" >Verifying linker symbols<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Initializing_the_stack_pool\" >Initializing the stack pool<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Initializing_the_memory_allocator_and_size_classes\" >Initializing the memory allocator and size classes<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Virtual_memory_reservation\" >Virtual memory reservation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Initializing_the_heap\" >Initializing the heap<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Initializing_the_cache\" >Initializing the cache<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#Further_reading\" >Further reading<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"The_starting_sequence\"><\/span>The starting sequence<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>We will pick up our exploration from where we left off last time\u2014the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.rt0_go<\/code> function. There is still a part of it that we haven\u2019t looked at.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n        CLD                         \/\/ convention is D is always left cleared\r\n        CALL    runtime\u00b7check(SB)\r\n\r\n        MOVL    16(SP), AX          \/\/ copy argc\r\n        MOVL    AX, 0(SP)\r\n        MOVQ    24(SP), AX          \/\/ copy argv\r\n        MOVQ    AX, 8(SP) \r\n        CALL    runtime\u00b7args(SB)\r\n        CALL    runtime\u00b7osinit(SB)\r\n        CALL    runtime\u00b7schedinit(SB)\r\n<\/pre>\n<p>The first instruction (<code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">CLD<\/code>) clears the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Direction_flag\" target=\"_blank\" rel=\"noopener noreferrer\">direction<\/a> flag of the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">FLAGS<\/code> register. This flag affects the direction of string processing. <\/p>\n<p>The next function is a call to the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.check<\/code> function, which is also not very valuable for our purposes. The runtime just tries to create instances of all built-in types, check their sizes and some other parameters, etc., and it <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">panics<\/code> if something goes wrong. You can easily explore this <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/runtime1.go#L136\" target=\"_blank\" rel=\"noopener noreferrer\">function<\/a> on your own.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Analyzing_arguments\"><\/span>Analyzing arguments<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The next function, <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/runtime1.go#L48\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.Args<\/a>, is somewhat more interesting. Apart from storing arguments (<code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">argc<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">argv<\/code>) in static variables, on Linux systems, it is responsible for analyzing the ELF auxiliary vector and initializing <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">syscall<\/code> addresses.<\/p>\n<p>This requires some explanation. When the operating system loads a program into memory, it initializes the initial stack for this program with some data in a predefined format. At the top of the stack, lay the arguments\u2014pointers to environment variables. At the bottom, we can find the \u201cELF auxiliary vector,\u201d which is actually an array of records that contains some other useful information, for example, the number and size of program headers. (For more on the ELF auxiliary vector format, please check out <a href=\"http:\/\/articles.manugarg.com\/aboutelfauxiliaryvectors\" target=\"_blank\" rel=\"noopener noreferrer\">this article<\/a>.<\/p>\n<p>The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.Args<\/code> function is responsible for parsing this vector. Out of all the information that it contains, the runtime only uses <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">startupRandomData<\/code>, which mainly serves for initializing hashing functions and pointers to locations for some syscalls. The following variables are initialized as shown below.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n        __vdso_time_sym \r\n        __vdso_gettimeofday_sym \r\n        __vdso_clock_gettime_sym\r\n<\/pre>\n<p>They are used for obtaining the current time in different functions. All these variables have default values. This allows Golang to use the <a href=\"https:\/\/www.ukuug.org\/events\/linux2001\/papers\/html\/AArcangeli-vsyscalls.html\" target=\"_blank\" rel=\"noopener noreferrer\">vsyscall<\/a> mechanism to call the corresponding functions.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"The_runtimeosinit_and_runtimeschedinit_functions\"><\/span>The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.osinit<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.schedinit<\/code> functions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The next function called during the startup sequence is <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/os1_linux.go#L172\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.osinit<\/a>. On Linux systems, the only thing it does is initialize the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">ncpu<\/code> variable that holds the number of CPUs in the system. This is done via a syscall.<\/p>\n<p><a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/proc1.go#L40\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.schedinit<\/a>\u2014the next function in the startup sequence\u2014is more interesting. It begins by obtaining the current goroutine, which is, in fact, a pointer to the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/runtime2.go#L211\" target=\"_blank\" rel=\"noopener noreferrer\">g<\/a> structure. We have talked about how this pointer is stored when discussing the TLS implementation. Next, it calls <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/race1.go#L110\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.raceinit<\/a>. We will skip the discussion of <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.raceinit<\/code>, because this function is normally not called when checking for race conditions is not enabled. After that, some other initialization functions are called.<\/p>\n<p>Let\u2019s explore them one at a time.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Initializing_traceback\"><\/span>Initializing traceback<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/traceback.go#L58\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.tracebackinit<\/a> function is responsible for initializing traceback. Traceback is a stack of functions that were called before we got to the current point of execution. For example, we can see it each time a panic occurs. Traceback is generated by a given program counter by calling a function called <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/traceback.go#L120\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.gentraceback<\/a>. For this function to work, we need to know the addresses of some built-in functions (e.g., because we don\u2019t want them to be included into the traceback). <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.tracebackinit<\/code> is responsible for initializing these addresses.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Verifying_linker_symbols\"><\/span>Verifying linker symbols<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Linker symbols are data emitted by the linker to the executable and the object file. Most of these symbols\u2019 contents have been discussed in <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\" target=\"_blank\" rel=\"noopener noreferrer\">Golang Internals, Part 3: The Linker, Object Files, and Relocations<\/a>. In the runtime package, linker symbols are mapped to the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/symtab.go#L37\" target=\"_blank\" rel=\"noopener noreferrer\">moduledata<\/a> struct. The <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/symtab.go#L95\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.moduledataverify<\/a> function is responsible for performing some checks against this data and verifying that it has the correct structure and is not corrupted.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Initializing_the_stack_pool\"><\/span>Initializing the stack pool<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>To understand the next initialization step, you need a bit of knowledge about how stack growth is implemented in Go. When a new goroutine is created, a small fixed-size stack is allocated for it. When the stack reaches some threshold, its size is doubled, and the stack is copied to another location.<\/p>\n<p>There is still a lot of detail on how reaching this threshold is determined and how Go adjusts pointers in the stack. We have already touched on some of these things in our previous blog posts, when talking about the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">stackguard0<\/code> field and function metadata. You can also find a lot of useful information on the subject in <a href=\"https:\/\/docs.google.com\/document\/d\/1wAaf1rYoM4S4gtnPh0zOlGzWtrZFQ5suE8qr2sD8uWQ\/pub\" target=\"_blank\" rel=\"noopener noreferrer\">this document<\/a>.<\/p>\n<p>Go uses a stack pool to cache currently unused stacks. The stack pool is an array initialized in the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/stack1.go#L54\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.stackinit<\/a> function. Each item in this array contains a linked list of stacks of the same size.<\/p>\n<p>Another variable initialized at this stage is <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.stackFreeQueue<\/code>. It also contains a linked list of stacks, but these are added to the list during garbage collection and are cleared after it is finished. Note that only 2 KB, 4 KB, 8 KB, and 16 KB stacks are cached. Larger ones are allocated directly.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Initializing_the_memory_allocator_and_size_classes\"><\/span>Initializing the memory allocator and size classes<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The process of memory allocation is described in this <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/malloc.go#L5\" target=\"_blank\" rel=\"noopener noreferrer\">source code comment<\/a>. We strongly encourage you to read it, if you want to understand how memory allocation works. Initialization of the memory allocator is located in the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/malloc.go#L216\" target=\"_blank\" rel=\"noopener noreferrer\">runtime.mallocinit<\/a> function, so let&#8217;s take a closer look at it.<\/p>\n<p>The first thing we can see here is that <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.mallocinit<\/code> is calling another function\u2014<a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/msize.go#L66\" target=\"_blank\" rel=\"noopener noreferrer\">initSizes<\/a>, which is responsible for calculating size classes. But what size does a class have? When allocating a small object (less than 32 KB), the Go runtime first rounds its size up to a predefined class size. So, the allocated block of memory can only have one of the predefined sizes that is usually larger than what is required for the object itself. This leads to a small memory wastage, but it enables you to easily re-use allocated memory blocks for different objects.<\/p>\n<p>The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">initSizes<\/code> function is responsible for calculating these classes. At the top of this function, we can see the following code.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    align := 8\r\n\tfor size := align; size &lt;= _MaxSmallSize; size += align {\r\n\t\tif size&amp;(size-1) == 0 { \r\n\t\t\tif size &gt;= 2048 {\r\n\t\t\t\talign = 256\r\n\t\t\t} else if size &gt;= 128 {\r\n\t\t\t\talign = size \/ 8\r\n\t\t\t} else if size &gt;= 16 {\r\n\t\t\t\talign = 16 \r\n\u2026\r\n\t\t\t}\r\n\t\t}\r\n<\/pre>\n<p>As we can see, the smallest two size classes are 8 and 16 bytes. Subsequent classes are located in every 16 bytes up to 128 bytes. From 128 to 2,048 bytes, classes are located in every size\/8 bytes. After 2,048 bytes, size classes are located in every 256 bytes.<\/p>\n<p>The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">initSizes<\/code> method initializes the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/msize.go#L49\" target=\"_blank\" rel=\"noopener noreferrer\">class_to_size<\/a> array, which converts a class (here, by class we mean its index in the class list) to its size. It also initializes the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/msize.go#L50\" target=\"_blank\" rel=\"noopener noreferrer\">class_to_allocnpages<\/a> array that stores data on how many memory pages should be obtained from the OS to fill one object of a given class, and two more arrays\u2014<a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/msize.go#L53\" target=\"_blank\" rel=\"noopener noreferrer\">size_to_class8<\/a> and <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/msize.go#L54\" target=\"_blank\" rel=\"noopener noreferrer\">size_to_class128<\/a>. These serve for conversion from object size to a corresponding class index. The first one converts object sizes smaller than 1 KB, and the second one is for object sizes of 1\u201332 KB.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Virtual_memory_reservation\"><\/span>Virtual memory reservation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The next thing the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mallocinit<\/code> function does is reserve virtual memory for future allocations. Let\u2019s see how this is done on x64 architectures. First of all, we need to initialize the following variables:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\t\tarenaSize := round(_MaxMem, _PageSize)\r\n\t\tbitmapSize = arenaSize \/ (ptrSize * 8 \/ 4)\r\n\t\tspansSize = arenaSize \/ _PageSize * ptrSize\r\n\t\tspansSize = round(spansSize, _PageSize)\r\n<\/pre>\n<ul>\n<li style=\"margin-bottom: 6px;\"><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">arenaSize<\/code> is the maximum amount of virtual memory that can be reserved for object allocations. On 64-bit architectures, it is equal to 512 GB.<\/li>\n<li style=\"margin-bottom: 6px;\"><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">bitmapSize<\/code> corresponds to the amount of memory reserved for the garbage collector (GC) bitmap. This is a special memory type used to show where exactly pointers are located in memory and whether the object, which is pointed to, is marked by GC.<\/li>\n<li><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">spansSize<\/code> is the amount of memory reserved for storing an array of pointers to all memory spans. A memory span is a structure that wraps a block of memory used for object allocations.<\/li>\n<\/ul>\n<p>Once all these variables have been calculated, the actual reservation is done.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npSize = bitmapSize + spansSize + arenaSize + _PageSize  \r\np = uintptr(sysReserve(unsafe.Pointer(p), pSize, &amp;reserved)) \r\n<\/pre>\n<p>Finally, we can initialize the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mheap.go#L65\" target=\"_blank\" rel=\"noopener noreferrer\">mheap<\/a> global variable that is used as central storage for all memory-related objects.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    p1 := round(p, _PageSize)\r\n\r\n\tmheap_.spans = (**mspan)(unsafe.Pointer(p1))\r\n\tmheap_.bitmap = p1 + spansSize\r\n\tmheap_.arena_start = p1 + (spansSize + bitmapSize)\r\n\tmheap_.arena_used = mheap_.arena_start\r\n\tmheap_.arena_end = p + pSize\r\n\tmheap_.arena_reserved = reserved\r\n<\/pre>\n<p>Note that, from the beginning, <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap_.arena_used<\/code> is initialized with the same address as <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap_.arena_start<\/code>, because nothing has been allocated yet.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Initializing_the_heap\"><\/span>Initializing the heap<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Next, the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mheap.go#L273\" target=\"_blank\" rel=\"noopener noreferrer\">mHeap_Init<\/a> function is called. The first thing that is done here is allocator initialization.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\t    fixAlloc_Init(&amp;h.spanalloc, unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &amp;memstats.mspan_sys)\r\n\t    fixAlloc_Init(&amp;h.cachealloc, unsafe.Sizeof(mcache{}), nil, nil, &amp;memstats.mcache_sys)\r\n\t    fixAlloc_Init(&amp;h.specialfinalizeralloc, unsafe.Sizeof(specialfinalizer{}), nil, nil, &amp;memstats.other_sys)\r\n\t    fixAlloc_Init(&amp;h.specialprofilealloc, unsafe.Sizeof(specialprofile{}), nil, nil, &amp;memstats.other_sys)\r\n<\/pre>\n<p>To better understand what an allocator is, let\u2019s see how it is utilized. All allocators operate in the <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mfixalloc.go#L54\" target=\"_blank\" rel=\"noopener noreferrer\">fixAlloc_Alloc<\/a> function, called each time we want to allocate new <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mheap.go#L101\" target=\"_blank\" rel=\"noopener noreferrer\">mspan<\/a>, <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mcache.go#L11\" target=\"_blank\" rel=\"noopener noreferrer\">mcache<\/a>, <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mheap.go#L1009\" target=\"_blank\" rel=\"noopener noreferrer\">specialfinalizer<\/a>, and <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mheap.go#L1050\" target=\"_blank\" rel=\"noopener noreferrer\">specialprofile<\/a> structs. The main part of this function is as follows below.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    if uintptr(f.nchunk) &lt; f.size {\r\n\t\tf.chunk = (*uint8)(persistentalloc(_FixAllocChunk, 0, f.stat))\r\n\t\tf.nchunk = _FixAllocChunk\r\n\t}\r\n<\/pre>\n<p>It allocates memory, but instead of allocating the actual size of the structure\u2014<code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">f.size<\/code> bytes\u2014we set aside <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/malloc.go#L130\" target=\"_blank\" rel=\"noopener noreferrer\">_FixAllocChunk<\/a> bytes (currently, equal to 16 KB). The rest of the available space is stored in the allocator. Next time, we need to allocate a structure of the same type, it will not require calling <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/malloc.go#L828\" target=\"_blank\" rel=\"noopener noreferrer\">persistentalloc<\/a>, which can be time consuming.<\/p>\n<p>The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">persistentalloc<\/code> function is responsible for allocating memory that should not be garbage collected. Its workflow is as follows.<\/p>\n<ol>\n<li style=\"margin-bottom: 6px;\">If the allocated block is larger than 64 KB, it is allocated directly from OS memory.<\/li>\n<li style=\"margin-bottom: 6px;\">Otherwise, we first need to find a persistent allocator:<\/li>\n<\/ol>\n<ul style=\"margin-left: 20px;\">\n<li style=\"margin-bottom: 6px;\">A persistent allocator is attached to each processor. This is done to avoid using locks when working with a persistent allocator. So, we try to use a persistent allocator from the current processor.<\/li>\n<li style=\"margin-bottom: 6px;\">If we cannot obtain information about the current processor, a global system allocator is used.<\/li>\n<\/ul>\n<ol>\n<li value=\"3\" style=\"margin-bottom: 6px;\">If the allocator does not have enough free memory in its cache, we set aside more memory from the OS.<\/li>\n<li style=\"margin-bottom: 6px;\">The required amount of memory is returned from the allocator\u2019s cache.<\/li>\n<\/ol>\n<p>The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">persistentalloc<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">fixAlloc_Alloc<\/code> functions work in similar ways. It is possible to say that those functions implement two levels of caching. You should also be aware that <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">persistentalloc<\/code> is used not only in <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">fixAlloc_Alloc<\/code>, but also in many other places where we need to allocate persistent memory.<\/p>\n<p>Let\u2019s return to the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mHeap_Init<\/code> function. One more important question to answer here is how the four structures, for which allocators were initialized at the beginning of this function, are used:<\/p>\n<ul>\n<li style=\"margin-bottom: 6px;\"><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mspan<\/code> is a wrapper for a memory block that should be garbage collected. We have talked about it when discussing size classes. A new <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mspan<\/code> is created when we need to allocate a new object of a particular size class.<\/li>\n<li style=\"margin-bottom: 6px;\"><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mcache<\/code> is a struct attached to each processor. It is responsible for caching spans. The reason for having a separate cache for each processor is to avoid locking.<\/li>\n<li style=\"margin-bottom: 6px;\"><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">specialfinalizeralloc<\/code> is a struct that is allocated when the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.SetFinalizer<\/code> function is called. This can be done if we want the system to execute some cleanup code when an object is cleared. A good example is the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">os.NewFile<\/code> function that associates a finalizer with each new file. This finalizer should close the OS file descriptor.<\/li>\n<li><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">specialprofilealloc<\/code> is a struct employed in the memory profiler.<\/li>\n<\/ul>\n<p>After initializing memory allocators, the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mHeap_Init<\/code> function initializes lists by calling <a href=\"https:\/\/github.com\/golang\/go\/blob\/go1.5.1\/src\/runtime\/mheap.go#L863\" target=\"_blank\" rel=\"noopener noreferrer\">mSpanList_Init<\/a>, which is very simple. All it does is initialize the first entry for the linked list. The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap<\/code> struct contains a few such linked lists.<\/p>\n<ul>\n<li style=\"margin-bottom: 6px;\"><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap.free<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap.busy<\/code> are arrays that contain <em>free<\/em> and <em>busy<\/em> lists with spans for large objects (larger than 32 KB, but smaller than 1 MB). Each of these arrays contains one item per each possible size. Here, sizes are measured in pages. One page is equal to 32 KB. The first item contains a list with 32 KB spans, the second one contains a list with 64 KB spans, and so on.<\/li>\n<li><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap.freelarge<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap.busylarge<\/code> are free and busy lists for objects larger than 1 MB.<\/li>\n<\/ul>\n<p>The next step is to initialize <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap.central<\/code>, which stores spans for small objects (less than 32 KB). In <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mheap.central<\/code>, lists are grouped accordingly to their size classes. Initialization is very similar to what we have seen previously. It is simply initialization of linked lists for each free list.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Initializing_the_cache\"><\/span>Initializing the cache<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Now, we are almost done with memory allocator initialization. The last thing that is left in the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mallocinit<\/code> function is <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mcache<\/code> initialization.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\t_g_ := getg()\r\n\t_g_.m.mcache = allocmcache()\r\n<\/pre>\n<p>Here, we first obtain the current goroutine. Each goroutine contains a link to the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">m<\/code> struct, which is a wrapper around the operating system thread. Inside this struct, there is the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mcache<\/code> field that is initialized in these lines. The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">allocmcache<\/code> function calls <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">fixAlloc_Alloc<\/code> to initialize a new <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mcache<\/code> struct. We have already discussed how allocation is done and the meaning of this struct (see above).<\/p>\n<p>A careful reader may notice that we have previously said <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mcache<\/code> is attached to each processor, but now we see that it is attached to the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">m<\/code> struct, which corresponds to an OS process, not a processor. And that is correct\u2014<code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">mcache<\/code> is initialized only for those threads that are currently executed and it is relocated to another thread whenever a process switch occurs.<\/p>\n<p>In the next post, we will continue discussing the bootstrap process by looking at how the garbage collector is initialized and how the main goroutine is started. Meanwhile, don\u2019t hesitate to share your thoughts and suggestions in the comments below.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Further_reading\"><\/span>Further reading<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-1-main-concepts-and-project-structure\/\">Golang Internals, Part 1: Main Concepts and Project Structure<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-2-diving-into-the-go-compiler\/\">Golang Internals, Part 2: Diving Into the Go Compiler<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\">Golang Internals, Part 3: The Linker, Object Files, and Relocations<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/\">Golang Internals, Part 4: Object Files and Function Metadata<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-5-the-runtime-bootstrap-process\/\">Golang Internals, Part 5: the Runtime Bootstrap Process<\/a><\/li>\n<\/ul>\n<hr \/>\n<p><center><small>This post was written by <b>Siarhei Matsiukevich<\/b> and edited by <a href=\"https:\/\/www.altoros.com\/blog\/author\/sophie.turol\/\">Sophia Turol<\/a> and <a href=\"https:\/\/www.altoros.com\/blog\/author\/alex\/\">Alex Khizhniak<\/a>.<\/small><\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<\/p>\n<p>All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6<\/p>\n<p>&nbsp;<\/p>\n<p>This post is the continuation of our Golang Internals series. It explores the bootstrapping process, which is key to understanding the Go runtime, in more detail. In this part, we will run [&#8230;]<\/p>\n","protected":false},"author":94,"featured_media":47479,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[214],"tags":[895],"class_list":["post-47447","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-research-and-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization | Altoros<\/title>\n<meta name=\"description\" content=\"This blog post explains how to initialize traceback, the stack pool, a memory allocator, size classes, the heap, etc.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization | Altoros\" \/>\n<meta property=\"og:description\" content=\"All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 &nbsp; This post is the continuation of our Golang Internals series. It explores the bootstrapping process, which is key to understanding the Go runtime, in more detail. In this part, we will run [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2015-10-15T12:27:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-27T15:09:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Siarhei Matsiukevich\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Siarhei Matsiukevich\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\",\"name\":\"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png\",\"datePublished\":\"2015-10-15T12:27:30+00:00\",\"dateModified\":\"2019-11-27T15:09:36+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png\",\"width\":1024,\"height\":768},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\",\"url\":\"https:\/\/www.altoros.com\/blog\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.altoros.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9\",\"name\":\"Siarhei Matsiukevich\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg\",\"caption\":\"Siarhei Matsiukevich\"},\"description\":\"Siarhei Matsiukevich is a Cloud Engineer and Go Developer at Altoros. With 6+ years in software engineering, he is an expert in cloud automation and designing architectures for complex cloud-based systems. An active member of the Go community, Siarhei is a frequent contributor to open-source projects, such as Ubuntu and Juju Charms.\",\"url\":\"https:\/\/www.altoros.com\/blog\/author\/siarhei-matsiukevich\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization | Altoros","description":"This blog post explains how to initialize traceback, the stack pool, a memory allocator, size classes, the heap, etc.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/","og_locale":"en_US","og_type":"article","og_title":"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization | Altoros","og_description":"All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 &nbsp; This post is the continuation of our Golang Internals series. It explores the bootstrapping process, which is key to understanding the Go runtime, in more detail. In this part, we will run [...]","og_url":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/","og_site_name":"Altoros","article_published_time":"2015-10-15T12:27:30+00:00","article_modified_time":"2019-11-27T15:09:36+00:00","og_image":[{"width":1024,"height":768,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png","type":"image\/png"}],"author":"Siarhei Matsiukevich","twitter_misc":{"Written by":"Siarhei Matsiukevich","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/","url":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/","name":"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png","datePublished":"2015-10-15T12:27:30+00:00","dateModified":"2019-11-27T15:09:36+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/10\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization-v1.png","width":1024,"height":768},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9","name":"Siarhei Matsiukevich","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg","caption":"Siarhei Matsiukevich"},"description":"Siarhei Matsiukevich is a Cloud Engineer and Go Developer at Altoros. With 6+ years in software engineering, he is an expert in cloud automation and designing architectures for complex cloud-based systems. An active member of the Go community, Siarhei is a frequent contributor to open-source projects, such as Ubuntu and Juju Charms.","url":"https:\/\/www.altoros.com\/blog\/author\/siarhei-matsiukevich\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/94"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=47447"}],"version-history":[{"count":27,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47447\/revisions"}],"predecessor-version":[{"id":50560,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47447\/revisions\/50560"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/47479"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=47447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=47447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=47447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}