Menu
CoddyTech

Thu gom rác trong Go

Thuộc phần Lập trình hướng đối tượng trong hành trình GO của Coddy. Bài học 23 trên 107.

Không giống như các ngôn ngữ như C hay C++, Go tự động quản lý bộ nhớ thông qua thu gom rác (GC). Bạn không cần tự giải phóng bộ nhớ khi dùng xong. Go runtime theo dõi vùng nhớ nào vẫn đang được sử dụng và thu hồi phần còn lại.

Khi cấp phát bộ nhớ bằng new(), make() hoặc tạo biến, bộ thu gom rác của Go sẽ theo dõi các vùng bộ nhớ này. Khi chương trình không còn phần nào có thể truy cập đến một giá trị, GC sẽ tự động giải phóng vùng bộ nhớ đó.

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p thoát ra vùng nhớ heap, GC sẽ quản lý vùng nhớ đó
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // Khi không còn dùng person, GC thu hồi bộ nhớ
}

Trong ví dụ này, struct Person được cấp phát trên heap vì nó được trả về từ hàm. Trình biên dịch Go thực hiện phân tích thoát (escape analysis) để xác định biến có thể nằm trên stack hay phải chuyển sang heap. Bộ thu gom rác chỉ quản lý bộ nhớ heap.

Việc quản lý bộ nhớ tự động này giúp bạn tập trung xây dựng ứng dụng mà không phải lo về rò rỉ bộ nhớ do quên giải phóng bộ nhớ. Tuy nhiên, hiểu rằng GC tồn tại sẽ giúp bạn viết code hiệu quả hơn bằng cách giảm thiểu việc cấp phát không cần thiết khi hiệu năng quan trọng.

challenge icon

Thử thách

Dễ

Hãy xây dựng một trình quản lý phiên để minh họa cách bộ thu gom rác (garbage collector) của Go xử lý bộ nhớ cho các đối tượng thoát ra heap. Bạn sẽ tạo các phiên được cấp phát động và trả về từ các hàm, để GC quản lý vòng đời của chúng.

Bạn sẽ sắp xếp code trong hai tệp:

  • session.go: Định nghĩa một cấu trúc Session với các trường ID (chuỗi), Username (chuỗi) và Data (một lát chuỗi). Tạo hàm NewSession nhận ID và tên người dùng, cấp phát một Session mới trên heap (bằng cách trả về một con trỏ) và khởi tạo lát Data rỗng. Thêm cả phương thức AddData với receiver là con trỏ để nối một chuỗi vào lát Data của phiên, và phương thức Summary trả về một chuỗi đã định dạng để hiển thị thông tin chi tiết của phiên.
  • main.go: Đọc thông tin phiên từ đầu vào, tạo một phiên bằng hàm khởi tạo, thêm một vài mục dữ liệu vào phiên rồi hiển thị phần tóm tắt. Vì phiên được tạo bên trong một hàm và được trả về dưới dạng con trỏ, nó thoát ra heap, nơi bộ thu gom rác sẽ quản lý phiên.

Đầu vào sẽ gồm:

  • Dòng 1: ID phiên
  • Dòng 2: Tên người dùng
  • Dòng 3: Mục dữ liệu đầu tiên cần thêm
  • Dòng 4: Mục dữ liệu thứ hai cần thêm

Phương thức Summary của bạn sẽ trả về một chuỗi theo định dạng sau:

Session [ID] for user [Username]
Data entries: [count]
- [entry1]
- [entry2]

Ví dụ, với sess-001, alice, login và view_dashboard, đầu ra sẽ là:

Session sess-001 for user alice
Data entries: 2
- login
- view_dashboard

Điểm mấu chốt ở đây là hàm NewSession tạo một Session rồi trả về con trỏ đến nó. Điều này khiến Session "thoát" ra heap thay vì nằm trên ngăn xếp, nhờ đó nó có thể được thu gom rác khi không còn tham chiếu nào đến nó. Code của bạn không cần giải phóng bộ nhớ này theo cách thủ công: Go tự xử lý.

Tự làm thử

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Đọc ID phiên
	sessionID, _ := reader.ReadString('\n')
	sessionID = sessionID[:len(sessionID)-1]

	// Đọc tên người dùng
	username, _ := reader.ReadString('\n')
	username = username[:len(username)-1]

	// Đọc mục dữ liệu đầu tiên
	data1, _ := reader.ReadString('\n')
	data1 = data1[:len(data1)-1]

	// Đọc mục dữ liệu thứ hai
	data2, _ := reader.ReadString('\n')
	data2 = data2[:len(data2)-1]

	// TODO: Tạo phiên mới bằng hàm (function) NewSession
	// Phiên sẽ chuyển sang vùng nhớ heap vì ta trả về một con trỏ

	// TODO: Thêm các mục dữ liệu vào phiên bằng phương thức (method) AddData

	// TODO: In ra bản tóm tắt phiên bằng phương thức Summary
	fmt.Println("")
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Go online