Go의 가비지 컬렉션
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 23번째.
C나 C++과 같은 언어와 달리, Go는 가비지 컬렉션(GC)을 통해 메모리 관리를 자동으로 처리합니다. 사용을 마친 메모리를 수동으로 해제할 필요가 없습니다. Go 런타임은 어떤 메모리가 여전히 사용 중인지 추적하고 나머지를 회수합니다.
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 구조체는 함수에서 반환되기 때문에 힙에 할당됩니다. Go의 컴파일러는 변수가 스택에 남아 있을 수 있는지 또는 힙으로 이동해야 하는지를 결정하기 위해 이스케이프 분석을 수행합니다. 가비지 컬렉터는 힙 메모리만 관리합니다.
이 automatic memory management 덕분에, 잊어버린 메모리 해제로 인한 memory leaks를 걱정하지 않고 애플리케이션 구축에 집중할 수 있습니다. 하지만 GC가 존재한다는 점을 이해하면, 성능이 중요한 경우 불필요한 할당을 최소화하여 더 효율적인 코드를 작성하는 데 도움이 됩니다.
챌린지
쉬움Go의 가비지 컬렉터가 힙으로 이스케이프되는 객체의 메모리를 어떻게 처리하는지 보여 주는 세션 관리자를 만들어 보겠습니다. 동적으로 할당되고 함수에서 반환되는 세션을 생성하여 GC가 수명 주기를 관리하도록 합니다.
코드를 두 파일에 나누어 구성합니다:
session.go:ID(문자열),Username(문자열),Data(문자열 슬라이스) fields를 포함하는Session구조체를 Define합니다. ID와 username을 전달받아 힙에 새 Session을 할당하고(포인터를 반환하여), Data 슬라이스를 empty 상태로 초기화하는NewSessionfunction을 Create합니다. 또한 pointer receiver를 사용하는AddDatamethod를 추가하여 문자열을 세션의 Data 슬라이스에 appends하고, 세션 details를 보여 주는 formatted 문자열을 반환하는Summarymethod도 추가합니다.main.go: 입력에서 세션 정보를 읽고, constructor function을 사용하여 세션을 Create한 다음, 일부 data entries를 추가하고 세션 요약을 표시합니다. 세션이 function 내부에서 생성되고 pointer로 반환되므로 힙으로 이스케이프되며, 그곳에서 가비지 컬렉터가 이를 manage합니다.
다음 입력이 제공됩니다:
- 1번째 줄: Session ID
- 2번째 줄: Username
- 3번째 줄: 추가할 first data entry
- 4번째 줄: 추가할 second data entry
Summary method는 다음 형식의 문자열을 반환해야 합니다:
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여기서 핵심은 NewSession function이 Session을 Create하고 그에 대한 pointer를 반환한다는 점입니다. 이로 인해 Session은 스택에 남는 대신 힙으로 "escape"하며, 더 이상 참조가 남아 있지 않으면 가비지 컬렉션 대상이 됩니다. 이 메모리를 수동으로 해제할 필요는 없습니다. 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("")
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서직접 연습해 보세요: 온라인 Go 컴파일러