1. defer
: Cleanup with Guaranteed Execution
What it does: Runs a function after its parent function finishes.
package main
import "os"
func main() {
file, _ := os.Open("data.txt")
defer file.Close() // Deferred cleanup
}
Memory Segmentation
+-------------------+ Lowest Address
| Code |
|-------------------|
| main() | // Compiled instructions
| os.Open() | // File-opening logic
| file.Close() | // Cleanup instructions
+-------------------+
| Data |
|-------------------|
| "data.txt" | // Filename (immutable)
+-------------------+
| Stack |
|-------------------|
| main() frame |
| file (pointer) →| // Points to OS resource
+-------------------+
| Heap |
|-------------------|
| (Empty) | // No allocations here
+-------------------+ Highest Address
Key Points:
-
defer
addsfile.Close()
to a LIFO stack of functions to run aftermain()
. -
file
is a pointer to an OS resource (handled outside Go’s memory).
2. panic
& recover
: Crash and Rescue
package main
func main() {
defer func() {
if r := recover(); r != nil {
println("Recovered:", r)
}
}()
panic("critical failure")
}
Memory Segmentation
+-------------------+ Lowest Address
| Code |
|-------------------|
| main() |
| recover() logic |
+-------------------+
| Data |
|-------------------|
| "critical failure"| // Panic message
+-------------------+
| Stack |
|-------------------|
| main() frame |
| recover defer |
+-------------------+
| Heap |
|-------------------|
| (Empty) | // No heap allocations
+-------------------+ Highest Address
Key Points:
-
panic
stores its message in the data segment (immutable). -
recover()
checks if a panic occurred. Works only inside deferred functions.
3. Heap Escape in Action
func main() {
x := 42
defer func() {
println(x) // x escapes to heap
}()
x = 100
}
Memory Segmentation
+-------------------+ Lowest Address
| Code |
|-------------------|
| main() |
| closure logic |
+-------------------+
| Data |
|-------------------|
| (No constants) |
+-------------------+
| Stack |
|-------------------|
| main() frame |
| x (int) → | // Points to heap
+-------------------+
| Heap |
|-------------------|
| x (int = 100) | // Captured by closure
+-------------------+ Highest Address
Why?:
- The deferred closure outlives
main()
, forcingx
to the heap. - Verify with
go build -gcflags="-m" main.go
:
./main.go:4:3: ... x escapes to heap
Rules to Remember
-
defer
- Use for cleanup (files, network connections).
- Arguments are evaluated immediately.
-
panic
- Crashes the program unless
recover()
is used. - Stores messages in the data segment.
- Crashes the program unless
-
recover()
- Only works inside deferred functions.
- Resets program state after a panic.