Go는 어떤 종류의 가비지 컬렉션을 사용합니까?


111

Go는 가비지 수집 언어입니다.

http://golang.org/doc/go_faq.html#garbage_collection

여기서는 그것이 표시 및 청소 가비지 수집기라고 말하고 있지만 세부 사항을 조사하지 않고 교체 작업이 진행 중입니다.

여전히 마크 앤 스윕인가요? 보수적입니까, 정확합니까? 세대 적입니까?


2
2018년 7월를 통해 이동 가비지 컬렉터까지의 역사의 긴 설명을 참조 blog.golang.org/ismmkeynote
와일드 카드

답변:


117

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 구현을 어렵게 만듭니다.

또한 현재 가비지 수집기는 어느 정도의 병렬 처리 기능을 갖추고 있으므로 멀티 코어 시스템에서 더 빠르게 실행할 수 있습니다.
uriel

3
@uriel : 예, 제 답변의 첫 번째 항목 인 "(병렬 구현)"이라는 텍스트에서 이것을 언급했습니다.

이 답변이 아직 최신입니까?
Kim Stebel

C # 가비지 수집기는 정확하며 C #에서는 스트라이크 멤버에 대한 참조를 가질 수 있고 C #에는 안전하지 않은 모드가 있지만 안전하지 않은 구현과 비교하는 방법이 확실하지 않습니다
skyde

3
좋은 기록 로그를 만들기 위해이 답변을 1.5.x로 업데이트하는 것은 어떻습니까?
Ismael 2016

32

( Go 1.8-Q1 2017, 아래 참조 )

다음 Go 1.5 동시 가비지 수집기는 gc가 "지속"할 수 있다는 것을 포함합니다.
다음은 이 백서에 제시된 제안 으로 Go 1.5 용으로 만들 수 있지만 Go의 gc를 이해하는 데 도움이됩니다.

1.5 이전 의 상태 볼 수 있습니다 (Stop The World : STW)

Go 1.5 이전에 Go는 병렬 STW ( stop-the-world ) 수집기를 사용했습니다.
STW 수집에는 많은 단점이 있지만 적어도 예측 가능하고 제어 가능한 힙 증가 동작이 있습니다.

https://40.media.tumblr.com/49e6556b94d75de1050c62539680fcf9/tumblr_inline_nr6qq8D9FE1sdck2n_540.jpg

( GopherCon 2015 프레젠테이션 " Go GC : Go 1.5에서 지연 시간 문제 해결 "의 사진 )

STW 수집기의 유일한 튜닝 손잡이는 수집 간의 상대적인 힙 증가 인 "GOGC"였습니다. 기본 설정 인 100 %는 이전 컬렉션에서 힙 크기가 라이브 힙 크기보다 두 배가 될 때마다 가비지 컬렉션을 트리거했습니다.

https://docs.google.com/drawings/image?id=sLJ_JvGfPfPnojLlEGLCWkw&rev=1&h=113&w=424&ac=1

STW 수집기의 GC 타이밍.

Go 1.5에는 동시 수집기가 도입되었습니다 .
이것은 STW 수집에 비해 많은 장점이 있지만 가비지 수집기가 실행되는 동안 응용 프로그램이 메모리를 할당 할 수 있기 때문에 힙 증가를 제어하기가 더 어려워집니다 .

https://40.media.tumblr.com/783c6e557b427a5c023520578740eb94/tumblr_inline_nr6qqpmaJx1sdck2n_540.jpg

( GopherCon 2015 프레젠테이션 " Go GC : Go 1.5에서 지연 시간 문제 해결 "의 사진 )

동일한 힙 증가 한계를 달성하려면 런타임이 가비지 콜렉션을 더 일찍 시작해야하지만 얼마나 빨리 가비지 콜렉션을 시작해야하는지 여부는 많은 변수에 따라 달라지며 그중 많은 변수는 예측할 수 없습니다.

  • 수집기를 너무 일찍 시작하면 애플리케이션이 너무 많은 가비지 수집을 수행하여 CPU 리소스를 낭비하게됩니다.
  • 수집기를 너무 늦게 시작하면 애플리케이션이 원하는 최대 힙 증가량을 초과합니다.

동시성을 희생하지 않고 올바른 균형을 이루려면 가비지 수집기를 신중하게 진행해야합니다.

GC 페이싱은 힙 증가와 가비지 수집기가 사용하는 CPU의 두 가지 차원을 따라 최적화하는 것을 목표로합니다.

https://docs.google.com/drawings/image?id=sEZYCf7Mc0E0EGmy4gho3_w&rev=1&h=235&w=457&ac=1

GC 페이싱의 디자인은 다음 네 가지 구성 요소로 구성됩니다.

  1. GC주기에 필요한 스캔 작업량에 대한 추정기,
  2. 뮤 테이터가 힙 할당이 힙 목표에 도달 할 때까지 추정 된 스캔 작업량을 수행하는 메커니즘
  3. mutator가 CPU 예산을 충분히 활용하지 못하는 경우 백그라운드 스캔을위한 스케줄러
  4. GC 트리거를위한 ​​비례 컨트롤러.

이 디자인 은 CPU 시간과 힙 시간이라는 두 가지 시간 관점의 균형을 맞 춥니 다 .

  • CPU 시간 은 표준 벽시계 시간과 비슷하지만 GOMAXPROCS시간이 더 빠릅니다.
    즉, GOMAXPROCS8이면 매 월 1 초마다 8 개의 CPU 초가 지나고 GC는 월초마다 2 초의 CPU 시간을 얻습니다.
    CPU 스케줄러는 CPU 시간을 관리합니다.
  • 통로의 힙 시간은 바이트 단위로 측정하고, 뮤 테이터가 할당으로 이동 전달.

힙 시간과 벽 시간 간의 관계는 할당 속도에 따라 달라지며 지속적으로 변경 될 수 있습니다.
Mutator는 힙 시간의 경과를 관리하여 힙이 목표 크기에 도달 할 때까지 예상 스캔 작업이 완료되었는지 확인합니다.
마지막으로 트리거 컨트롤러는이 두 가지 시간보기를 함께 연결하는 피드백 루프를 생성하여 힙 시간과 CPU 시간 목표를 모두 최적화합니다.


20

다음은 GC의 구현입니다.

https://github.com/golang/go/blob/master/src/runtime/mgc.go

소스의 문서에서 :

GC는 뮤 테이터 스레드와 동시에 실행되며 유형이 정확하고 (정확한) 여러 GC 스레드가 병렬로 실행될 수 있습니다. 쓰기 장벽을 사용하는 동시 표시 및 스윕입니다. 그것은 세대가 아니고 압축되지 않습니다. 일반적인 경우 잠금을 제거하면서 조각화를 최소화하기 위해 P 할당 영역별로 분리 된 크기를 사용하여 할당이 수행됩니다.


8

Go 1.8 GC는 "STW 스택 재검색 제거" 라는 제안으로 다시 진화 할 수 있습니다.

Go 1.7에서 제한되지 않고 잠재적으로 중요 하지 않은 STW (stop-the-world) 시간의 남은 소스 는 스택 재검색입니다.

우리는 Yuasa 스타일 삭제 쓰기 배리어 [Yuasa '90]Dijkstra 스타일 삽입 쓰기 배리어 [Dijkstra '78] 를 결합한 하이브리드 쓰기 배리어로 전환하여 스택 재검색의 필요성을 제거 할 것을 제안합니다 .

예비 실험은 이것이 최악의 STW 시간을 50µs 미만으로 줄일 수 있음을 보여 주며 ,이 접근 방식을 사용하면 STW 마크 종료를 완전히 제거 할 수 있습니다.

발표는 여기에 당신은 관련 소스 커밋 볼 수 있습니다 d70b0fe 및 이전.


3

잘 모르겠지만 현재의 (팁) GC가 이미 병렬이거나 적어도 WIP라고 생각합니다. 따라서 stop-the-world 속성은 더 이상 적용되지 않거나 가까운 장래에 적용되지 않을 것입니다. 아마도 다른 누군가가 이것을 더 자세히 설명 할 수있을 것입니다.


7
그것은 세상을 멈추게합니다. GC는 세계가 중지 된 후 잠재적으로 병렬로 실행됩니다. 동시 GC를 의미했을 것입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.