讓我們來了解 Golang 如何處理變數以及逃脫分析是什麼。 Golang 有兩種在 Go 運行時環境中使用的記憶體分配資料類型,稱為堆疊和堆疊。
堆疊執行(輸入和輸出)操作的速度更快。函數內存取的變數會進入該堆疊。 例如:
package main import "fmt" func stackExample() int { a := 10 // Variable `a` is allocated on the stack b := 20 // Variable `b` is allocated on the stack result := a + b // `result` is also allocated on the stack return result // All stack variables are popped off when the function exits } func main() { result := stackExample() // Function call happens, variables are pushed to the stack fmt.Println(result) // Print the result }
這就是堆疊在 GoLang 中的工作原理。接下來是一堆。它是一個動態記憶體,即它的大小可以根據需要進行調整。這是堆分配的簡單範例。
package main import "fmt" func heapExample() *int { num := 42 // Variable `num` is created inside the function return &num // Returning the address of `num`, which escapes the function } func main() { ptr := heapExample() // The value pointed to by `ptr` is allocated on the heap fmt.Println(*ptr) // Accessing the heap-allocated variable through the pointer }
這裡由於函數傳回一個指向 num 的指針,Go 運行時偵測到 num 將在函數作用域之外被存取。結果,它在堆上而不是堆疊上分配 num。
堆疊用於儲存超出函數或 Goroutine 範圍的變數。有時,當變數的值非常大時,它會儲存在堆中。
理解了這兩個之後,就可以進入逃逸分析了。僅透過閱讀 Go 程式碼無法知道哪些變數將被分配到堆中。我們可以透過「逃逸分析」來理解這一點。所謂轉義,是指變數是否轉義了函數的作用域,決定了它是儲存在堆疊還是堆疊上。
像這樣運行go程式碼的建置指令
go build -gcflags '-m -l'
-m - 顯示逃逸分析的標誌。
-l - 停用內聯以保持堆疊追蹤準確。
取得此程式碼:
package main func escapeExample() *int { x := 42 return &x // x escapes because its address is returned } func noEscapeExample() int { y := 100 return y // y does not escape } func main() { _ = escapeExample() _ = noEscapeExample() }
結果如下:
./main.go:4:10: &x escapes to heap ./main.go:12:13: main escapes to heap
那麼,我們為什麼要做這些呢?當您調試效能問題時,此分析非常有用。變數最好儲存在堆疊中而不是堆中。您可以找到變數逃逸到堆的位置並重構程式碼以提高效率。
希望你今天學到新東西了。
我目前正在建立 LiveAPI,這是一個用於 API 文件生成的工具,請嘗試一下。
感謝您的閱讀。
以上是GoLang 超越基礎:逃逸分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!