The Stack and the Heap棧與堆__Rust

Ashe|||^_^發表於2024-04-21

Many programming languages don’t require you to think about the stack and the heap very often. 許多程式語言並不會要求你經常思考堆疊。But in a system programming language like Rust, whether a value is on the stack or the heap affects how the language behaves and why you have to make certain decisions. 但是對於Rust這樣的系統級程式語言來說,值儲存在棧或是堆中將直接影響語言的行為以及為什麼必須做出某些確切的決定。Parts of ownership will be described in relation on the stack and the heap later in this chapter, so here is a brief explanation in preparation.由於Rust中的所有權與其存在關聯,因此這是一個開胃菜(準備)的解釋。

Both the stack and the heap are parts of memory available to your code to use at runtime, but they are structured in different ways.棧與堆都是你程式碼在執行時所使用的記憶體。但是二者之間的結構存在一定不同之處。 The stack stores values in the order it gets them and removes the values in the opposite order. 棧空間儲存值與釋放值空間的順序相反。This is referred to as last in, first out. 被稱為後進先出。Think of a stack of plates: when you add more plates, you put them on top of the pile, and when you need a plate, you take one off the top.這裡有一疊盤子,堆放時只能從最上方堆疊,拿取時只能從最上方移除。 Adding or removing plates from the middle or bottom wouldn’t work as well! 從中間或底部來堆疊或移除盤子都是不恰當的!Adding data is called pushing onto the stack, and removing data is called popping off the stack.新增資料稱為入棧,移除資料稱為出棧。 All data stored on the stack must have a known, fixed size. Data with an unknown size at compile time or a size that might change must be stored on the heap instead.所有棧區儲存的資料必須是已知的、固定的記憶體大小。如果在編譯時資料時未知的記憶體大小或者可能會變化的記憶體大小,那麼該資料必須儲存在堆區間。

The Stack and the Heap棧與堆__Rust

The heap is less organized: when you put data on the heap, you request a certain amount of space. 堆區組織性較差,當你將資料儲存在堆中,你需要請求一定量的記憶體空間。The memory allocator finds an empty spot in the heap that is big enough, mark it as being in use, and returns a pointer, which is the address of that location. 記憶體分配器會找到一塊未被使用的、足夠的記憶體區域,將其標記為使用中,並返回指標(這塊記憶體區域的記憶體地址)。This process is called allocating on the heap and is sometimes abbreviated as just allocating(pushing values onto the stack is not considered allocating).這一過程被稱為堆上分配,有時會簡寫為allocating(入棧不被視為allocating)。 Because the pointer to the heap is a known, fixed size, you can store the pointer on the stack, but when you want the actual data, you must follow the pointer.因為指標是已知的、固定的記憶體大小,你可以在棧區儲存指標,如果你想獲取實際資料,則必須透過其記憶體地址來獲取。 Think of being seated at restaurant. When you enter, you state the number of people in your group, and the host finds an empty table that fits everyone and leads you there. If someone in your group comes late, they can ask where you’ve been seated to find you.試想一下餐廳的就座,當你進入餐廳,你會說明有多少人就餐,然後餐廳會安排一個(適用對應人數就餐的)空餘桌子給你們並帶領你們到該位置,如果你們一行人中有人來晚了,也可以根據就座的位置(記憶體地址)找到你們。

Pushing to the stack is faster than allocating on the heap because the allocator never has to search for a place to store new data;入棧比堆上分配更快,因為記憶體分配器不需要尋找儲存新資料的記憶體空間。 that location is always at the top of the stack. 其位置永遠在棧區的最上方。Comparatively, allocating space on the heap requires more work because the allocator must first find a big enough space to hold the data and then perform bookkeeping to prepare for the next allocation.相較而言,堆上分配需要做更多工作,因為記憶體分配器需要先尋找一個空餘的、足夠的記憶體空間來儲存資料,並記錄,為下一次分配做準備。

Accessing data in the heap is slower than accessing data on the stack because you have to follow a pointer to get there. 在堆中訪問資料比在棧中訪問資料更慢。Contemporary processors are faster if they jump around less in memory.對於現代處理器而言跳轉的記憶體區域越小執行速度越快。 Continuing the analogy, consider a server at a restaurant taking orders from many tables. 繼續類比,一名餐廳服務員給許多桌客人點餐。It’s most efficient to get all the orders at one table before moving on the next table.最有效率(快)的方式就是一桌接著一桌來點餐。 Taking an order from table A, then an order from table B, then one from table A again, and then one from B again would be a much slower process.若是點餐順序從A到B再到A再到B,將會是更慢的過程。 By the same token, a processor can do its job better if it works on data that’s close to other data(as it is on the stack) rather than farther away(as it can be on the heap).同樣道理,處理器在資料之間(記憶體距離)更近的條件下執行程式碼時會表現更好。

When your code calls a function, the values passed into the function(including, potentially, pointers to data on the heap) and the function’s local variables get pushed onto the stack. When the function is over, those values get popped off the stack.當你的程式碼呼叫函式時,傳遞給函式的值(可能包括指向堆上資料的指標)和函式的區域性變數入棧,當函式結束時,這些值出棧。

Keeping track of what parts of code are using what data on the heap, minimizing the amount of duplicate data on the heap, and cleaning up unused data on the heap so you won’t run out of space are all problems that ownership addresses. 跟蹤程式碼的哪些部分正在使用堆上的哪些資料,最大限度地減少堆上的重複資料量,以及清理堆上未使用的資料,這樣就不會耗盡空間,這些都是所有權解決的問題。Once you understand ownership, you won’t need to think about the stack and the heap very often, but knowing that the main purpose of ownership is to manage heap data can help explain why it works the way it dose.一旦理解了所有權,您就不需要經常考慮堆疊和堆,但是知道所有權的主要目的是管理堆資料可以幫助解釋為什麼它會這樣工作。

相關文章