{"id":47360,"date":"2015-03-18T15:05:04","date_gmt":"2015-03-18T12:05:04","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=47360"},"modified":"2019-11-27T18:08:37","modified_gmt":"2019-11-27T15:08:37","slug":"golang-internals-part-4-object-files-and-function-metadata","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/","title":{"rendered":"Golang Internals, Part 4: Object Files and Function Metadata"},"content":{"rendered":"<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> | <strong>Part 4<\/strong> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-5-the-runtime-bootstrap-process\/\">Part 5<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\">Part 6<\/a><\/small><\/center><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-47361\" style=\"margin:10px\" alt=\"Golang-Part-4-Object-Files-and-Function-Metadata\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/10\/Golang-Part-4-Object-Files-and-Function-Metadata1.png\"  width=\"120\" height=\"160\" \/><\/p>\n<p>Today, we\u2019ll take a closer look at the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Func<\/code> structure and discuss a few details on how garbage collection works in Go.<\/p>\n<p>This post is a continuation of <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\">\u201cGolang Internals, Part 3: The Linker and Go Object Files\u201d<\/a> and uses the same sample program. So, we strongly advise that you read the previous part before moving forward.<\/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-4-object-files-and-function-metadata\/#The_structure_of_function_metadata\" >The structure of function metadata<\/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-4-object-files-and-function-metadata\/#How_a_garbage_collector_uses_function_metadata\" >How a garbage collector uses function metadata<\/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-4-object-files-and-function-metadata\/#Further_reading\" >Further reading<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"The_structure_of_function_metadata\"><\/span>The structure of function metadata<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The main idea behind relocations should be clear from Part 3. Now let\u2019s take a  look at the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Func<\/code> structure of the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">main<\/code> method.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">Func: &amp;goobj.Func{\r\n    Args:    0,\r\n    Frame:   8,\r\n    Leaf:    false,\r\n    NoSplit: false,\r\n    Var:     {\r\n    },\r\n    PCSP:   goobj.Data{Offset:255, Size:7},\r\n    PCFile: goobj.Data{Offset:263, Size:3},\r\n    PCLine: goobj.Data{Offset:267, Size:7},\r\n    PCData: {\r\n        {Offset:276, Size:5},\r\n    },\r\n    FuncData: {\r\n        {\r\n            Sym:    goobj.SymID{Name:&quot;gclocals\u00b73280bececceccd33cb74587feedb1f9f&quot;, Version:0},\r\n         Offset: 0,\r\n     },\r\n     {\r\n         Sym:    goobj.SymID{Name:&quot;gclocals\u00b73280bececceccd33cb74587feedb1f9f&quot;, Version:0},\r\n               Offset: 0,\r\n           },\r\n       },\r\n       File: {&quot;\/home\/adminone\/temp\/test.go&quot;},\r\n   },<\/pre>\n<p>You can think of this structure as function metadata emitted by the compiler in the object file and used by the Go runtime. This <a href=\"https:\/\/docs.google.com\/document\/d\/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o\/pub\" target=\"_blank\" rel=\"noopener noreferrer\">article<\/a> explains the exact format and meaning of the different fields in <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Func<\/code>. Now, we will try to show you how this metadata is used in the runtime.<\/p>\n<p>Inside the runtime package, this metadata is mapped on the following struct.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">type _func struct {\r\n\tentry   uintptr \/\/ start pc\r\n\tnameoff int32   \/\/ function name\r\n\r\n\targs  int32 \/\/ in\/out args size\r\n\tframe int32 \/\/ legacy frame size; use pcsp if possible\r\n\r\n\tpcsp      int32\r\n\tpcfile    int32\r\n\tpcln      int32\r\n\tnpcdata   int32\r\n\tnfuncdata int32\r\n}<\/pre>\n<p>You can see that not all the information that was in the object file has been mapped directly. Some of the fields are only used by the linker. Still, the most interesting here are the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pcsp<\/code>, <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pcfile<\/code>, and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pcln<\/code> fields, which are used when a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Program_counter\" target=\"_blank\" rel=\"noopener noreferrer\">program counter<\/a> is translated into a stack pointer, file name, and line accordingly.<\/p>\n<p>This is required, for example, when <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">panic<\/code> occurs. At that exact moment, the runtime only knows about the program counter of the current assembly instruction that has triggered <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">panic<\/code>. So, the runtime uses that counter to obtain the current file, line number, and full stack trace. The file and line number are resolved directly, using the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pcfile<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pcln<\/code> fields. The stack trace is resolved recursively, using <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pcsp<\/code>.<\/p>\n<p>Now that we have a program counter, the question is, how do we get a corresponding line number? To answer it, you need to look through assembly code and understand how line numbers are stored in the object file.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">0x001a 00026 (test.go:4)\tMOVQ\t$1,(SP)\r\n\t0x0022 00034 (test.go:4)\tPCDATA\t$0,$0\r\n\t0x0022 00034 (test.go:4)\tCALL\t,runtime.printint(SB)\r\n\t0x0027 00039 (test.go:5)\tADDQ\t$8,SP\r\n\t0x002b 00043 (test.go:5)\tRET\t,<\/pre>\n<p>We can see that program counters from 26 to 38 inclusive correspond to line number 4 and counters from 39 to <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">next_function_program_counter - 1<\/code> correspond to line number 5. For space efficiency, it is enough to store the following map.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">26 - 4\r\n39 - 5\r\n\u2026<\/pre>\n<p>This is almost exactly what the compiler does. The <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pcln<\/code> field points to a particular offset in a map that corresponds to the first program counter of the current function. Knowing this offset and also the offset of the first program counter of the next function, the runtime can use binary search to find the line number that corresponds to the given program counter.<\/p>\n<p>In Go, this idea is generalized. Not only a line number or stack pointer can be mapped to a program counter, but also any integer value. This is done via the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">PCDATA<\/code> instruction. Each time, the linker finds the following instruction.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">0x0022 00034 (test.go:4)\tPCDATA\t$0,$0<\/pre>\n<p>It doesn\u2019t generate any actual assembler instructions. Instead, it stores the second argument of this instruction in a map with the current program counter, while the first argument indicates what map is used. With this first argument, we can easily add new maps, which meaning is known to the compiler and runtime but is opaque to the linker.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"How_a_garbage_collector_uses_function_metadata\"><\/span>How a garbage collector uses function metadata<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The last thing that still needs to be clarified in function metadata is the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">FuncData<\/code> array. It contains information necessary for garbage collection. Go uses the <a href=\"http:\/\/www.brpreiss.com\/books\/opus5\/html\/page424.html\" target=\"_blank\" rel=\"noopener noreferrer\">mark-and-sweep<\/a> garbage collector (GC) that operates in two stages. During the first stage (mark), it traverses through all objects that are still in use and marks them as reachable. All the unmarked objects are removed during the second (sweep) stage.<\/p>\n<p>So, the garbage collector starts by looking for a reachable object in several known locations, such as global variables, processor registers, stack frames, and pointers in objects that have already been reached. However, if you think about it carefully, looking for pointers in stack frames is far from a trivial task. So, when the runtime is performing garbage collection, how does it distinguish whether a variable in the stack is a pointer or belongs to a non-pointer type? This is where <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">FuncData<\/code> comes into play.<\/p>\n<p>For each function, the compiler creates two variables. One contains a bitmap vector for the arguments area of the stack frame. The other one contains a bitmap for the rest of the frame that includes all the local variables of pointer types defined in the function. Each of these variables tells the garbage collector, where exactly in the stack frame the pointers are located, and that information is enough for it to do its job.<\/p>\n<p>It is also worth mentioning that like <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">PCDATA<\/code>, <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">FUNCDATA<\/code> is also generated by a pseudo-Go assembly instruction.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">0x001a 00026 (test.go:3)\tFUNCDATA\t$0,gclocals\u00b73280bececceccd33cb74587feedb1f9f+0(SB)<\/pre>\n<p>The first argument of this instruction indicates, whether this is function data for arguments or a local variables area. The second one is actually a reference to a hidden variable that contains a GC mask.<\/p>\n<p>In the upcoming posts, we will investigate the Go bootstrap process, which is the key to understanding how the Go runtime works.<\/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-5-the-runtime-bootstrap-process\/\">Golang Internals, Part 5: the Runtime Bootstrap Process<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\">Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization<\/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>All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6<\/p>\n<\/p>\n<p>Today, we\u2019ll take a closer look at the Func structure and discuss a few details on how garbage collection works in Go.<\/p>\n<p>This post is a continuation of \u201cGolang Internals, Part 3: The [&#8230;]<\/p>\n","protected":false},"author":94,"featured_media":47366,"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-47360","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 4: Object Files and Function Metadata | Altoros<\/title>\n<meta name=\"description\" content=\"This blog post explores the structure of function metadata, and how a garbage collector uses it.\" \/>\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-4-object-files-and-function-metadata\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Golang Internals, Part 4: Object Files and Function Metadata | Altoros\" \/>\n<meta property=\"og:description\" content=\"All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 Today, we\u2019ll take a closer look at the Func structure and discuss a few details on how garbage collection works in Go. This post is a continuation of \u201cGolang Internals, Part 3: The [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2015-03-18T12:05:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-27T15:08:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.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=\"5 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-4-object-files-and-function-metadata\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/\",\"name\":\"Golang Internals, Part 4: Object Files and Function Metadata | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.png\",\"datePublished\":\"2015-03-18T12:05:04+00:00\",\"dateModified\":\"2019-11-27T15:08:37+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.png\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.png\",\"width\":1024,\"height\":768},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Golang Internals, Part 4: Object Files and Function Metadata\"}]},{\"@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 4: Object Files and Function Metadata | Altoros","description":"This blog post explores the structure of function metadata, and how a garbage collector uses it.","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-4-object-files-and-function-metadata\/","og_locale":"en_US","og_type":"article","og_title":"Golang Internals, Part 4: Object Files and Function Metadata | Altoros","og_description":"All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 Today, we\u2019ll take a closer look at the Func structure and discuss a few details on how garbage collection works in Go. This post is a continuation of \u201cGolang Internals, Part 3: The [...]","og_url":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/","og_site_name":"Altoros","article_published_time":"2015-03-18T12:05:04+00:00","article_modified_time":"2019-11-27T15:08:37+00:00","og_image":[{"width":1024,"height":768,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.png","type":"image\/png"}],"author":"Siarhei Matsiukevich","twitter_misc":{"Written by":"Siarhei Matsiukevich","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/","url":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/","name":"Golang Internals, Part 4: Object Files and Function Metadata | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.png","datePublished":"2015-03-18T12:05:04+00:00","dateModified":"2019-11-27T15:08:37+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.png","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-4-object-files-and-function-metadata.png","width":1024,"height":768},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Golang Internals, Part 4: Object Files and Function Metadata"}]},{"@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\/47360","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=47360"}],"version-history":[{"count":9,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47360\/revisions"}],"predecessor-version":[{"id":47847,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47360\/revisions\/47847"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/47366"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=47360"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=47360"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=47360"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}