Menu
Coddy logo textTech

Сборка мусора в Go

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 23 из 107.

В отличие от таких языков, как C или C++, Go автоматически управляет memory с помощью сборки мусора (GC). Вам не нужно вручную освобождать memory, когда вы заканчиваете с ней работу. Среда выполнения Go отслеживает, какая memory всё ещё используется, и возвращает остальную.

Когда вы выделяете память с помощью new(), make() или создавая переменные, сборщик мусора Go отслеживает эти выделения. Как только значение становится недоступным для любой части вашей программы, GC автоматически освобождает эту память.

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p уходит в кучу, GC будет управлять им
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // Когда person больше не используется, GC освобождает память
}

В этом примере структура Person выделяется в heap, потому что возвращается из function. Компилятор Go выполняет escape analysis, чтобы определить, может ли переменная оставаться в стеке или должна переместиться в heap. Сборщик мусора управляет только heap memory.

Это автоматическое управление memory означает, что ты можешь сосредоточиться на создании своего приложения, не беспокоясь об утечках memory из-за забытых освобождений. Однако понимание того, что существует GC, помогает писать более эффективный код, сводя к минимуму ненужные выделения, когда важна производительность.

challenge icon

Задание

Легко

Давайте создадим менеджер сессий, демонстрирующий, как сборщик мусора Go обрабатывает memory объектов, которые escape в heap. Вы создадите сессии, которые выделяются динамически и возвращаются из функций, позволяя GC управлять их жизненным циклом.

Вы организуете код в двух файлах:

  • session.go: Define структуру Session с полями ID (string), Username (string) и Data (срез строк). Create NewSession function, которая принимает ID и username, выделяет новый Session в heap (возвращая pointer) и инициализирует срез Data как empty. Также добавьте метод AddData с pointer receiver, который appends строку к срезу Data сессии, и метод Summary, который возвращает formatted строку с details сессии.
  • main.go: Прочитайте информацию о сессии из входных данных, создайте сессию с использованием вашей конструкторской function, добавьте в неё несколько entries данных и выведите сводку сессии. Поскольку сессия создаётся внутри function и возвращается как pointer, она escape в heap, где сборщик мусора будет ею управлять.

Будут предоставлены следующие входные данные:

  • Строка 1: ID сессии
  • Строка 2: Username
  • Строка 3: Первая entry данных для добавления
  • Строка 4: Вторая entry данных для добавления

Ваш метод Summary должен возвращать строку в следующем формате:

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

Например, если заданы sess-001, alice, login и view_dashboard, результат должен быть следующим:

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

Главная идея заключается в том, что ваша function NewSession creates Session и возвращает pointer на него. Это causes Session "escape" в heap вместо того, чтобы оставаться в стеке, благодаря чему он становится eligible для сборки мусора, когда ссылок на него больше не остаётся. Вашему коду не нужно вручную освобождать эту memory: Go обрабатывает её automatically.

Попробуйте сами

package main

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

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

	// Читать ID сессии
	sessionID, _ := reader.ReadString('\n')
	sessionID = sessionID[:len(sessionID)-1]

	// Читать имя пользователя
	username, _ := reader.ReadString('\n')
	username = username[:len(username)-1]

	// Читать первую запись данных
	data1, _ := reader.ReadString('\n')
	data1 = data1[:len(data1)-1]

	// Читать вторую запись данных
	data2, _ := reader.ReadString('\n')
	data2 = data2[:len(data2)-1]

	// TODO: Создать новую сессию с помощью функции NewSession
	// Сессия уйдёт в кучу, поскольку мы возвращаем указатель

	// TODO: Добавить записи данных в сессию с помощью метода AddData

	// TODO: Вывести сводку сессии с помощью метода Summary
	fmt.Println("")
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Go