Garbage Collection in Go
Part of the Object Oriented Programming section of Coddy's GO journey — lesson 23 of 107.
Unlike languages such as C or C++, Go handles memory management automatically through garbage collection (GC). You don't need to manually free memory when you're done with it. The Go runtime tracks which memory is still in use and reclaims the rest.
When you allocate memory using new(), make(), or by creating variables, Go's garbage collector monitors these allocations. Once a value is no longer reachable by any part of your program, the GC automatically frees that memory.
func createPerson() *Person {
p := &Person{Name: "Alice", Age: 30}
return p // p escapes to heap, GC will manage it
}
func main() {
person := createPerson()
fmt.Println(person.Name)
// When person is no longer used, GC reclaims memory
}In this example, the Person struct is allocated on the heap because it's returned from the function. Go's compiler performs escape analysis to determine whether a variable can stay on the stack or must move to the heap. The garbage collector only manages heap memory.
This automatic memory management means you can focus on building your application without worrying about memory leaks from forgotten deallocations. However, understanding that GC exists helps you write more efficient code by minimizing unnecessary allocations when performance matters.
Challenge
EasyLet's build a session manager that demonstrates how Go's garbage collector handles memory for objects that escape to the heap. You'll create sessions that are allocated dynamically and returned from functions, letting the GC manage their lifecycle.
You'll organize your code across two files:
session.go: Define aSessionstruct withID(string),Username(string), andData(a slice of strings) fields. Create aNewSessionfunction that takes an ID and username, allocates a new Session on the heap (by returning a pointer), and initializes the Data slice as empty. Also add anAddDatamethod with a pointer receiver that appends a string to the session's Data slice, and aSummarymethod that returns a formatted string showing the session details.main.go: Read session information from input, create a session using your constructor function, add some data entries to it, and display the session summary. Since the session is created inside a function and returned as a pointer, it escapes to the heap where the garbage collector will manage it.
The following inputs will be provided:
- Line 1: Session ID
- Line 2: Username
- Line 3: First data entry to add
- Line 4: Second data entry to add
Your Summary method should return a string in this format:
Session [ID] for user [Username]
Data entries: [count]
- [entry1]
- [entry2]For example, given sess-001, alice, login, and view_dashboard, your output should be:
Session sess-001 for user alice
Data entries: 2
- login
- view_dashboardThe key insight here is that your NewSession function creates a Session and returns a pointer to it. This causes the Session to "escape" to the heap rather than staying on the stack, making it eligible for garbage collection once no references to it remain. Your code doesn't need to manually free this memory—Go handles it automatically.
Cheat sheet
Go uses garbage collection (GC) for automatic memory management. You don't need to manually free memory.
The garbage collector tracks memory allocations and reclaims memory that is no longer reachable by your program.
func createPerson() *Person {
p := &Person{Name: "Alice", Age: 30}
return p // p escapes to heap, GC will manage it
}
func main() {
person := createPerson()
fmt.Println(person.Name)
// When person is no longer used, GC reclaims memory
}Go's compiler performs escape analysis to determine whether a variable stays on the stack or moves to the heap. Variables that escape to the heap (like returned pointers) are managed by the garbage collector.
The GC only manages heap memory, not stack memory. Stack memory is automatically freed when a function returns.
Try it yourself
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Read session ID
sessionID, _ := reader.ReadString('\n')
sessionID = sessionID[:len(sessionID)-1]
// Read username
username, _ := reader.ReadString('\n')
username = username[:len(username)-1]
// Read first data entry
data1, _ := reader.ReadString('\n')
data1 = data1[:len(data1)-1]
// Read second data entry
data2, _ := reader.ReadString('\n')
data2 = data2[:len(data2)-1]
// TODO: Create a new session using NewSession function
// The session will escape to the heap since we return a pointer
// TODO: Add the data entries to the session using AddData method
// TODO: Print the session summary using the Summary method
fmt.Println("")
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of Go OOP
External FilesGo Workspace & ModulesPackages & ImportsExported vs Unexported NamesIntroduction to OOP in GoStructs as ClassesDefining Methods on StructsPointer vs Value ReceiversStruct InitializationConstructor FunctionsRecap - Simple Calculator4Interfaces
Introduction to InterfacesImplicit ImplementationInterface as ContractEmpty Interface (any)Type AssertionType SwitchInterface CompositionStringer & Error InterfacesRecap - Shape Calculator7Encapsulation
Exported vs Unexported FieldsPackage-Level EncapsulationGetter & Setter MethodsInformation Hiding in GoRecap - Student Records10Generics (Go 1.18+)
Introduction to GenericsType ParametersType ConstraintsGeneric StructsGeneric Methods WorkaroundRecap - Generic Collection2Types & Structs Deep Dive
Basic & Composite TypesCustom Type DefinitionsStruct TagsAnonymous StructsNested StructsZero Values & DefaultsRecap - Contact Book5Composition Over Inheritance
Why Go Has No InheritanceStruct Embedding BasicsMethod PromotionEmbedding Multiple StructsEmbedding vs AggregationShadowing Embedded MethodsRecap - Employee Hierarchy8Error Handling & OOP
The error InterfaceCustom Error TypesError Wrapping (fmt.Errorf)Sentinel Errorserrors.Is() and errors.As()Panic, Defer, and RecoverRecap - File Parser3Pointers & Memory
Pointer Basics in GoPointers to StructsPass by Value vs ReferenceThe new() FunctionGarbage Collection in GoRecap - Linked List Builder6Polymorphism in Go
Polymorphism via InterfacesDuck Typing in GoInterface Satisfaction RulesPolymorphic CollectionsDependency InjectionRecap - Payment Processor9Concurrency & OOP
Goroutines BasicsChannels & CommunicationBuffered vs Unbuffered ChanSelect Statementsync.Mutex & sync.RWMutexsync.WaitGroupThread-Safe Struct DesignRecap - Worker Pool