2012-09-05 4 views
18

가비지 컬렉터를 피하거나 최소화하려는 경우가있을 수 있으므로 어떻게해야하는지 알고 싶습니다.Go에서 가비지 수집을 최소화하는 방법은 무엇입니까?

나는 다음 하나가 올바른지 생각 :

  • 함수의 시작 부분에 변수를 선언합니다.
  • 슬라이스 대신 배열을 사용합니다.

더 이상?

+0

이와 같은 최적화 작업을 수행하기 전에 먼저 프로필을 작성해야합니다. 프로파일 링에 대한 [this] (http://blog.golang.org/2011/06/profiling-go-programs.html) 블로그 항목을 확인하십시오. 또한 가비지 수집을 최적화합니다. 좋은 출발이되어야할까요? – Christian

+4

왜 이것을 닫았습니까? 질문 : 가비지 수집을 피하는 방법은 무엇입니까? 힙 할당을 피하십시오 (특정 참조 된 예제 포함). 문제는 관련성이 높고 구체적이며 그 답은 논쟁의 여지가없는 것처럼 보입니다. – user634175

답변

21

쓰레기를 피하는 것은 비교적 간단합니다. 할당이 이루어지는 위치를 이해하고 할당을 피할 수 있는지 확인해야합니다.

먼저 함수 시작 부분에 변수를 선언하면 도움이되지 않습니다. 컴파일러는 차이점을 알지 못합니다. 그러나 인간은 그 차이를 알고 그것을 귀찮게 할 것입니다.

슬라이스 대신 배열을 사용하면되지만, 이는 참조 해제되지 않은 배열을 스택에 배치하기 때문입니다. 배열에는 함수간에 값 (복사 된)으로 전달된다는 사실과 같은 다른 문제가 있습니다. 스택에있는 것은 함수가 반환 될 때 해제되기 때문에 "가비지 아님"입니다. 함수를 벗어날 수있는 모든 포인터 또는 슬라이스는 가비지 수집기가 어느 시점에서 처리해야하는 힙에 배치됩니다.

할 수있는 최선의 방법은 할당을 피하는 것입니다. 필요하지 않은 많은 양의 데이터로 작업을 마쳤 으면 다시 사용하십시오. 이것은 이동 블로그의 profiling tutorial에서 사용되는 방법입니다. 나는 그것을 읽는 것이 좋습니다.

프로파일 링 자습서 이외의 다른 예 : []intxs이라는 슬라이스가 있다고 가정 해 보겠습니다. 조건에 도달 할 때까지 지속적으로 []int에 추가 한 다음 다시 시작하므로 다시 시작할 수 있습니다. xs = nil을 수행하면 이제 슬라이스의 기본 배열을 수집 할 쓰레기로 선언합니다. Append는 다음에 xs를 사용할 때 xs를 재 할당합니다. 대신 xs = xs[:0]을 수행하는 경우 이전 배열을 유지하면서 재설정합니다.

가비지 생성을 피하려고하는 것은 조기 최적화입니다. 대부분의 코드는 중요하지 않습니다. 그러나 매번 실행될 때마다 많은 양을 할당하는 함수를 여러 번 찾을 수 있습니다. 또는 재사용 대신 재 할당 할 루프. 선외로 나가기 전에 병목 목을 볼 때까지 기다릴 것입니다.

29

Go에서 가비지 수집을 최소화하려면 힙 할당을 최소화해야합니다. 힙 할당을 최소화하려면 할당이 언제 발생 하는지를 알아야합니다.

다음 일 (적어도 이동 1로 GC 컴파일러)는 항상 원인 할당

다음 new 내장 함수 make 내장 함수를 사용
  • 를 사용

    • (제외 가능성이 희박한 경우)
    • 값 유형이 슬라이스,지도 또는 구조체 인 경우 복합 리터럴 & 연산자
    • 인터페이스로 기계 단어. 예를 들어 문자열, 슬라이스 및 일부 구조체는 기계어보다 큽니다.m이지도는 m[string(b)], 그리고 b는 변환 []byte
  • 입니다 : 이동 1.3으로
    • []byte, string 사이에, 그리고 []rune 변환)
    • , 컴파일러 특별한 경우이 식을 할당 할 수 있습니다 정수가 아닌 값을 string
    • defer
    • go 문 캡처 지역 변수

    다음 일이 세부 사항에 따라 원인 할당, 수

  • 기능 리터럴 :

    • 변수의 주소를 복용합니다. 주소는 암시 적으로 취할 수 있습니다. 예를 들어 a.b()a의 주소를 취할 수 있으며 a은 포인터가 아니고 b 메서드는 포인터 수신기 유형을 가질 수 있습니다. 사용
    • append 목록이 완전하도록하고 난되어 내장 기능
    • 지도

    에 요소를 추가 배열

  • 조각화 가변 인자 함수 또는 메소드
  • 를 호출 m 합리적으로 자신감을 가지지 만, 추가 또는 수정을 고려해 보니 기쁘다.

    할당이 어디에서 발생하는지 잘 모르는 경우 다른 사람이 제안하거나 컴파일러에서 생성 된 어셈블리를 조사 할 때 항상 프로필을 작성할 수 있습니다.

  • +1

    'go build -gcflags = "- m"'을 사용하면 컴파일러의 이스케이프 분석을 볼 수 있습니다. 가능한 경우 스택에'x : = make ([] byte, 42)'같은 것들을 넣는 것이 훨씬 낫습니다. –

    관련 문제