Analyzing Go Memory Layout and Object Dumping
The article demonstrates how to examine a running Go program’s memory layout by defining example structs, using unsafe.Sizeof/Alignof, dumping writable regions via a Bash script and GDB, and locating fields and string constants in the resulting memory dumps to verify object representation.
When handling memory leaks, the author explores how to inspect objects in a running Go program by visualizing its memory layout.
Before the analysis, basic Go memory concepts are introduced: memory alignment, struct size, and the fact that heap objects do not carry type information. The internal representation of a string is shown as a struct with a Data pointer and a Len field, and a slice (array) is represented by a struct with Data , Len , and Cap fields.
Two example structs are defined:
type User struct {
Name string
Age uint8
Sex uint8
class *Class
}
type Class struct {
CName string
Index uint
}Using unsafe.Sizeof and unsafe.Alignof , the memory layout of Class (24 bytes) and User (32 bytes) is printed, with a diagram of the byte ranges for each field.
A small Go program creates an instance of User , fills the fields, and runs indefinitely, allowing the process memory to be examined. The program also prints the PID.
package main
import (
"fmt"
"math/rand"
"os"
"os/signal"
"strconv"
)
var user *User
func main() {
idx := rand.Intn(10)
user = &User{
Name: "zhangsan",
Age: 18,
Sex: 1,
class: &Class{
CName: "class-" + strconv.Itoa(idx),
Index: uint(idx),
},
}
fmt.Println(user)
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, os.Kill)
s := <-c
fmt.Println("receive signal -> ", s)
}To dump the memory of the running process, a Bash script dump-all-mem.sh reads /proc/$1/maps , filters writable regions, and invokes gdb --batch --pid $1 -ex "dump memory …" for each region, producing a set of .dump files.
#!/bin/bash
grep rw-p /proc/$1/maps | while read start stop; do
gdb --batch --pid $1 -ex "dump memory $1-$start-$stop.dump 0x$start 0x$stop"
doneThe resulting dump files are inspected with strings to locate the unique marker class- , and with hexdump -c to view the raw bytes. By calculating the offset of the marker within the dump (e.g., 00ae010 ), the absolute address c0000ae010 is derived.
Further analysis matches the bytes to the expected layout of Class (pointer, length, index) and User (name pointer, length, age, sex, padding, class pointer). The author verifies that the values printed by the program (Age=18, Sex=1, Name length=8) correspond to the bytes observed in the dump.
Finally, the location of the string "zhangsan" is found in the read‑only segment ( r--p ) of the process memory, confirming that constant strings reside in a non‑writable, non‑executable region.
The article concludes with references to Linux /proc/<pid>/maps analysis and Go memory inspection techniques.
Tencent Cloud Developer
Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.