speice.io/assets/js/761aff6b.101e026d.js

1 line
17 KiB
JavaScript
Raw Permalink Normal View History

"use strict";(self.webpackChunkspeice_io=self.webpackChunkspeice_io||[]).push([["7366"],{5623:function(e,n,t){t.r(n),t.d(n,{assets:function(){return i},contentTitle:function(){return l},default:function(){return d},frontMatter:function(){return r},metadata:function(){return s},toc:function(){return c}});var s=t(5238),o=t(5893),a=t(65);let r={slug:"2019/02/a-heaping-helping",title:"Allocations in Rust: Dynamic memory",date:new Date("2019-02-07T12:00:00.000Z"),authors:["bspeice"],tags:[]},l=void 0,i={authorsImageUrls:[void 0]},c=[{value:"Smart pointers",id:"smart-pointers",level:2},{value:"Collections",id:"collections",level:2},{value:"Heap Alternatives",id:"heap-alternatives",level:2},{value:"Tracing Allocators",id:"tracing-allocators",level:2}];function h(e){let n={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(n.p,{children:["Managing dynamic memory is hard. Some languages assume users will do it themselves (C, C++), and\nsome languages go to extreme lengths to protect users from themselves (Java, Python). In Rust, how\nthe language uses dynamic memory (also referred to as the ",(0,o.jsx)(n.strong,{children:"heap"}),") is a system called ",(0,o.jsx)(n.em,{children:"ownership"}),".\nAnd as the docs mention, ownership\n",(0,o.jsx)(n.a,{href:"https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html",children:"is Rust's most unique feature"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["The heap is used in two situations; when the compiler is unable to predict either the ",(0,o.jsx)(n.em,{children:"total size of\nmemory needed"}),", or ",(0,o.jsx)(n.em,{children:"how long the memory is needed for"}),", it allocates space in the heap."]}),"\n",(0,o.jsxs)(n.p,{children:["This happens\npretty frequently; if you want to download the Google home page, you won't know how large it is\nuntil your program runs. And when you're finished with Google, we deallocate the memory so it can be\nused to store other webpages. If you're interested in a slightly longer explanation of the heap,\ncheck out\n",(0,o.jsx)(n.a,{href:"https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#the-stack-and-the-heap",children:"The Stack and the Heap"}),"\nin Rust's documentation."]}),"\n",(0,o.jsxs)(n.p,{children:["We won't go into detail on how the heap is managed; the\n",(0,o.jsx)(n.a,{href:"https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html",children:"ownership documentation"}),' does a\nphenomenal job explaining both the "why" and "how" of memory management. Instead, we\'re going to\nfocus on understanding "when" heap allocations occur in Rust.']}),"\n",(0,o.jsx)(n.p,{children:"To start off, take a guess for how many allocations happen in the program below:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"fn main() {}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["It's obviously a trick question; while no heap allocations occur as a result of that code, the setup\nneeded to call ",(0,o.jsx)(n.code,{children:"main"})," does allocate on the heap. Here's a way to show it:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:'#![feature(integer_atomics)]\nuse std::alloc::{GlobalAlloc, Layout, System};\nuse std::sync::atomic::{AtomicU64, Ordering};\n\nstatic ALLOCATION_COUNT: AtomicU64 = AtomicU64::new(0);\n\nstruct CountingAllocator;\n\nunsafe impl GlobalAlloc for CountingAllocator {\n unsafe fn alloc(&self, layout: Layout) -> *mut u8 {\n ALLOCATION_COUNT.fetch_add(1, Ordering::SeqCst);\n System.alloc(layout)\n }\n\n unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {\n System.dealloc(ptr, layout);\n }\n}\n\n#[global_allocator]\nstatic A: CountingAllocator = CountingAllocator;\n\nfn main() {\n let x = ALLOCATION_COUNT.fetch_add(0, Ordering::SeqCst);\n println!("There were {} allocations before calling main!", x);\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["--\n",(0,o.jsx)(n.a,{href:"https://play.rust-lang.org/?ver