Go는 가비지 수집 언어입니다.
http://golang.org/doc/go_faq.html#garbage_collection
여기서는 그것이 표시 및 청소 가비지 수집기라고 말하고 있지만 세부 사항을 조사하지 않고 교체 작업이 진행 중입니다.
여전히 마크 앤 스윕인가요? 보수적입니까, 정확합니까? 세대 적입니까?
답변
Go 1.4+ 가비지 수집기에 대한 계획 :
- 하이브리드 stop-the-world / 동시 수집기
- 10ms 기한으로 제한된 세계 중지 부분
- 동시 수집기 실행 전용 CPU 코어
- 3 색 마크 앤 스윕 알고리즘
- 비 세대
- 비 압축
- 완전히 정확한
- 프로그램이 포인터를 이동하는 경우 약간의 비용이 발생합니다.
- 지연 시간이 짧지 만 Go 1.3 GC보다 처리량이 낮을 가능성이 높습니다.
Go 1.1 위에 Go 1.3 가비지 수집기 업데이트 :
- 동시 스윕 (일시 중지 시간 단축)
- 완전히 정확한
Go 1.1 가비지 수집기 :
- 마크 앤 스윕 (병렬 구현)
- 비 세대
- 비 압축
- 대부분 정확함 (스택 프레임 제외)
- 세상을 멈추다
- 비트 맵 기반 표현
- 프로그램이 메모리를 할당하지 않을 때 비용이 들지 않습니다.
- 객체에 대한 종료자를 지원합니다.
- 약한 참조에 대한 지원이 없습니다.
Go 1.0 가비지 수집기 :
- Go 1.1과 동일하지만 대부분 정확하지 않고 가비지 수집기는 보수적입니다. 보수적 인 GC는 [] byte와 같은 객체를 무시할 수 있습니다.
GC를 다른 것으로 교체하는 것은 논란의 여지가 있습니다. 예를 들면 다음과 같습니다.
- 매우 큰 힙을 제외하고 세대 별 GC가 전반적으로 더 빠른지 여부는 불분명합니다.
- 패키지 “안전하지 않음”은 완전 정밀 GC 및 압축 GC 구현을 어렵게 만듭니다.
답변
다음 Go 1.5 동시 가비지 수집기는 gc가 “지속”할 수 있다는 것을 포함합니다.
다음은 이 백서에 제시된 제안 으로 Go 1.5 용으로 만들 수 있지만 Go의 gc를 이해하는 데 도움이됩니다.
1.5 이전 의 상태 를 볼 수 있습니다 (Stop The World : STW)
Go 1.5 이전에 Go는 병렬 STW ( stop-the-world ) 수집기를 사용했습니다.
STW 수집에는 많은 단점이 있지만 적어도 예측 가능하고 제어 가능한 힙 증가 동작이 있습니다.
( GopherCon 2015 프레젠테이션 ” Go GC : Go 1.5에서 지연 시간 문제 해결 “의 사진 )
STW 수집기의 유일한 튜닝 손잡이는 수집 간의 상대적인 힙 증가 인 “GOGC”였습니다. 기본 설정 인 100 %는 이전 컬렉션에서 힙 크기가 라이브 힙 크기보다 두 배가 될 때마다 가비지 컬렉션을 트리거했습니다.
STW 수집기의 GC 타이밍.
Go 1.5에는 동시 수집기가 도입되었습니다 .
이것은 STW 수집에 비해 많은 장점이 있지만 가비지 수집기가 실행되는 동안 응용 프로그램이 메모리를 할당 할 수 있기 때문에 힙 증가를 제어하기가 더 어려워집니다 .
( GopherCon 2015 프레젠테이션 ” Go GC : Go 1.5에서 지연 시간 문제 해결 “의 사진 )
동일한 힙 증가 한계를 달성하려면 런타임이 가비지 콜렉션을 더 일찍 시작해야하지만 얼마나 빨리 가비지 콜렉션을 시작해야하는지 여부는 많은 변수에 따라 달라지며 그중 많은 변수는 예측할 수 없습니다.
- 수집기를 너무 일찍 시작하면 애플리케이션이 너무 많은 가비지 수집을 수행하여 CPU 리소스를 낭비하게됩니다.
- 수집기를 너무 늦게 시작하면 애플리케이션이 원하는 최대 힙 증가량을 초과합니다.
동시성을 희생하지 않고 올바른 균형을 이루려면 가비지 수집기를 신중하게 진행해야합니다.
GC 페이싱은 힙 증가와 가비지 수집기가 사용하는 CPU의 두 가지 차원을 따라 최적화하는 것을 목표로합니다.
GC 페이싱의 디자인은 다음 네 가지 구성 요소로 구성됩니다.
- GC주기에 필요한 스캔 작업량에 대한 추정기,
- 뮤 테이터가 힙 할당이 힙 목표에 도달 할 때까지 추정 된 스캔 작업량을 수행하는 메커니즘
- mutator가 CPU 예산을 충분히 활용하지 못하는 경우 백그라운드 스캔을위한 스케줄러
- GC 트리거를위한 비례 컨트롤러.
이 디자인 은 CPU 시간과 힙 시간이라는 두 가지 시간 관점의 균형을 맞 춥니 다 .
- CPU 시간 은 표준 벽시계 시간과 비슷하지만
GOMAXPROCS
시간이 더 빠릅니다.
즉,GOMAXPROCS
8이면 매 월 1 초마다 8 개의 CPU 초가 지나고 GC는 월초마다 2 초의 CPU 시간을 얻습니다.
CPU 스케줄러는 CPU 시간을 관리합니다.- 통로의 힙 시간은 바이트 단위로 측정하고, 뮤 테이터가 할당으로 이동 전달.
힙 시간과 벽 시간 간의 관계는 할당 속도에 따라 달라지며 지속적으로 변경 될 수 있습니다.
Mutator는 힙 시간의 경과를 관리하여 힙이 목표 크기에 도달 할 때까지 예상 스캔 작업이 완료되었는지 확인합니다.
마지막으로 트리거 컨트롤러는이 두 가지 시간보기를 함께 연결하는 피드백 루프를 생성하여 힙 시간과 CPU 시간 목표를 모두 최적화합니다.
답변
다음은 GC의 구현입니다.
https://github.com/golang/go/blob/master/src/runtime/mgc.go
소스의 문서에서 :
GC는 뮤 테이터 스레드와 동시에 실행되며 유형이 정확하고 (정확한) 여러 GC 스레드가 병렬로 실행될 수 있습니다. 쓰기 장벽을 사용하는 동시 표시 및 스윕입니다. 그것은 세대가 아니고 압축되지 않습니다. 일반적인 경우 잠금을 제거하면서 조각화를 최소화하기 위해 P 할당 영역별로 분리 된 크기를 사용하여 할당이 수행됩니다.
답변
Go 1.8 GC는 “STW 스택 재검색 제거” 라는 제안으로 다시 진화 할 수 있습니다.
Go 1.7에서 제한되지 않고 잠재적으로 중요 하지 않은 STW (stop-the-world) 시간의 남은 소스 는 스택 재검색입니다.
우리는 Yuasa 스타일 삭제 쓰기 배리어 [Yuasa ’90] 와 Dijkstra 스타일 삽입 쓰기 배리어 [Dijkstra ’78] 를 결합한 하이브리드 쓰기 배리어로 전환하여 스택 재검색의 필요성을 제거 할 것을 제안합니다 .
예비 실험은 이것이 최악의 STW 시간을 50µs 미만으로 줄일 수 있음을 보여 주며 ,이 접근 방식을 사용하면 STW 마크 종료를 완전히 제거 할 수 있습니다.
답변
잘 모르겠지만 현재의 (팁) GC가 이미 병렬이거나 적어도 WIP라고 생각합니다. 따라서 stop-the-world 속성은 더 이상 적용되지 않거나 가까운 장래에 적용되지 않을 것입니다. 아마도 다른 누군가가 이것을 더 자세히 설명 할 수있을 것입니다.