Go 언어에는 gc가 있습니다. GC는 자동 메모리 관리 메커니즘인 가비지 수집을 의미합니다. Go 언어는 GC를 지원하며 Go 언어의 객체 메모리 공간 재활용은 GC 메커니즘을 통해 완료됩니다. Go 언어의 GC는 No Generation(객체를 세대로 나누지 않음), No Sorting(재활용 과정에서 객체를 이동 및 정렬하지 않음), Concurrent(사용자 코드와 동시에 실행됨)의 세 가지 색상을 사용합니다. . 마크 및 스윕 알고리즘.
이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.
Java 언어가 널리 사용된 이후 GC 메커니즘이 인기를 얻었습니다. 최신 스크립팅 언어인 Python은 GC를 지원하고 GO도 GC를 지원합니다.
Go 언어와 C/C++ 언어의 주목할만한 특징은 Go에서 객체 메모리 공간의 재활용이 GC 메커니즘을 통해 완료된다는 점입니다. C++처럼 프로그래머가 수동으로 적용하고 해제할 필요가 없기 때문에 상대적으로 저렴합니다. Go에서는 메모리 누수가 발생하기 쉽습니다. 오늘은 Go의 GC 메커니즘에 대해 이야기하겠습니다.
GC란 무엇이며 어떤 용도로 사용되나요?
GC의 전체 이름은 자동 메모리 관리 메커니즘인 Garbage Collection입니다.
프로그램이 운영체제에서 요청한 메모리가 더 이상 필요하지 않게 되면 가비지 수집을 통해 이를 적극적으로 재활용하고 다른 코드에 재사용하여 메모리를 신청하거나 운영체제에 반환하는 메모리의 자동 재활용 프로세스입니다. -level resources. 가비지 수집입니다. 가비지 수집을 담당하는 프로그램 구성 요소는 가비지 수집기입니다.
쓰레기 수집은 실제로 “단순함은 복잡하다”의 완벽한 예입니다. 한편으로 프로그래머는 GC의 이점을 누리며 메모리에 대해 걱정하거나 수동으로 적용하고 해제할 필요가 없습니다. GC는 프로그램이 실행될 때 남은 메모리를 자동으로 해제합니다. 반면에 GC는 프로그래머에게 거의 보이지 않습니다. GC의 실행 타이밍과 실행 오버헤드를 제어할 수 있는 제어 가능한 API를 제공하여 프로그램에 특별한 최적화가 필요한 경우에만 나타납니다.
일반적으로 가비지 수집기의 실행 프로세스는 두 개의 반독립적인 구성 요소로 나뉩니다.
Mutator: 이 이름은 기본적으로 사용자 모드 코드를 나타냅니다. 가비지 수집기의 경우 사용자 모드 코드는 개체 간의 참조 관계만 수정합니다. 즉, 개체 그래프(개체 간의 참조 관계에 대한 방향성 그래프)에서만 작동합니다.
Collector: 가비지 수집을 담당하는 코드입니다.
GC의 루트 개체
루트 개체는 가비지 수집 용어로 루트 컬렉션이라고도 합니다. 가비지 수집기가 프로세스를 표시할 때 확인하는 첫 번째 개체입니다.
전역 변수: 프로그램의 수명 주기 전반에 걸쳐 존재하며 컴파일 타임에 결정될 수 있는 변수입니다.
실행 스택: 각 고루틴에는 스택의 변수와 할당된 힙 메모리 블록에 대한 포인터가 포함된 자체 실행 스택이 포함되어 있습니다.
레지스터: 레지스터의 값은 포인터를 나타낼 수 있으며 계산에 관련된 이러한 포인터는 일부 평가자가 할당한 힙 메모리 블록을 가리킬 수 있습니다.
GC 구현 방법
모든 GC 알고리즘의 존재는 추적 및 참조 계산이라는 두 가지 형식을 혼합하여 사용했기 때문일 수 있습니다.
Tracking GC
는 루트 개체부터 시작하여 개체 간 참조 정보를 기반으로 단계별로 진행하여 전체 힙을 스캔하고 보관해야 하는 개체가 결정되어 재활용 가능한 개체를 모두 재활용합니다. Go, Java 및 V8의 JavaScript 구현은 모두 GC를 추적합니다.
참조 카운팅 GC
각 객체 자체에는 참조 카운터가 포함되어 있으며, 카운터가 0에 도달하면 자동으로 재활용됩니다. 이 방법은 단점이 많기 때문에 고성능을 추구할 때에는 일반적으로 사용되지 않습니다. Python, Objective-C 등은 모두 참조 계산 GC입니다.
현재 더 일반적인 GC 구현 방법은 다음과 같습니다.
추적 유형은 다음과 같이 다양한 유형으로 구분됩니다.
마크 스윕: 루트 객체부터 시작하여 결정되는 객체 살아있음을 표시하고, 재활용이 가능한 물건을 정리합니다.
마크 정리: 마킹 과정에서 객체는 가능한 한 연속적인 메모리 조각으로 정리됩니다.
증분: 표시 및 청소 프로세스를 일괄적으로 실행하고 매번 작은 부분을 실행하여 가비지 수집을 점진적으로 진행하여 거의 실시간에 가깝고 일시 중지가 거의 발생하지 않습니다.
증분 정렬: 증분적으로 개체를 정렬하는 프로세스가 추가됩니다.
세대: 생존 기간에 따라 개체를 분류합니다. 생존 시간이 특정 값보다 짧은 개체는 젊은 세대, 생존 시간이 특정 값보다 큰 개체는 구세대, 앞으로는 개체를 분류합니다. 영구 세대는 재활용에 참여하지 않습니다. 그리고 개체는 세대별 가정(오래 살지 않으면 재활용되는 경향이 있고, 오래 살면 오래 사는 경향이 있음)에 따라 재활용됩니다.
참조 카운트: 객체 자체의 참조 카운트에 따라 재활용하고, 참조 카운트가 0에 도달하면 즉시 재활용합니다.
Go에서 GC 구현
Go의 경우 Go의 GC는 생성 없음(객체를 세대로 나누지 않음), 정렬 없음(재활용 과정에서 객체를 이동 및 수집하지 않음) 청소), 동시(사용자 코드와 동시에 실행됨) 3색 마크 스위핑 알고리즘입니다. [관련 권장 사항: Go 비디오 튜토리얼]
이유는 다음과 같습니다.
객체 조각 모음의 장점은 메모리 조각화 문제를 해결하고 순차 메모리 할당자의 사용을 "허용"한다는 것입니다. 하지만 Go 런타임 할당 알고리즘은 tcmalloc 기반이므로 기본적으로 조각화 문제가 없습니다. 그리고 순차 메모리 할당자는 다중 스레드 시나리오에 적합하지 않습니다. Go는 tcmalloc 기반의 최신 메모리 할당 알고리즘을 사용하므로 객체를 정렬해도 성능이 크게 향상되지는 않습니다.
세대 GC는 세대 가정에 의존합니다. 즉, GC는 모든 개체를 자주 확인하는 대신 새로 생성된 개체(생존 시간이 짧고 재활용 가능성이 높은 개체)에 주요 복구 대상을 둡니다. 그러나 Go의 컴파일러는 이스케이프 분석을 통해 대부분의 새로운 객체를 스택에 저장하고(스택은 직접 재활용됨) 오랫동안 존재해야 하는 객체만 가비지 수집이 필요한 힙에 할당됩니다. 즉, 세대별 GC에 의해 재활용된 수명이 짧은 객체는 Go에서 스택에 직접 할당되며, 고루틴이 종료되면 GC의 참여 없이 스택이 직접 재활용됩니다. 따라서 세대별 가정은 Come을 가져오지 않습니다. 직접적인 이점을 위해. 게다가 Go의 가비지 컬렉터는 사용자 코드와 동시에 실행되므로 STW 시간은 객체 생성 및 객체 크기와 아무런 관련이 없습니다. Go 팀은 일시 중지 시간을 줄이는 단일 목표보다는 GC가 사용자 코드와 동시에 실행되도록 하는 방법(적절한 CPU를 사용하여 가비지 수집 수행)에 더 중점을 두고 있습니다.
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 비디오를 방문하세요! !
위 내용은 Go 언어에는 GC가 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!