0Pricing
Go Academy · Lekcja

Wykrywanie wycieków i anulowanie

Zapewnianie kończenia pracy goroutines i zapobieganie wyciekom

Wykrywanie wycieków i anulowanie to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

Czym jest wyciek gorutyny?

Wyciek gorutyny występuje, gdy gorutyna zostanie uruchomiona, ale nigdy się nie kończy. Wyciekające gorutyny gromadzą się z czasem, zużywając pamięć stosu i czas procesora, aż proces zostanie zakończony.

Częsty wyciek: zablokowane odbieranie z kanału

Gorutyna oczekująca na odebranie z kanału, do którego nigdy nie zostanie wysłana żadna wartość, blokuje się na zawsze:

go func() {
    v := <-ch // leaks if no sender and ch is never closed
    use(v)
}()

Częsty wyciek: brak sygnału zakończenia

Gorutyna wykonująca pętlę for bez warunku wyjścia lub kanału done działa bez końca:

go func() {
    for {
        work()
        // no exit condition — leaks
    }
}()

Wykrywanie wycieków za pomocą goleak

go.uber.org/goleak sprawdza, czy na końcu testu nie pozostały wyciekające gorutyny:

func TestMyFunc(t *testing.T) {
    defer goleak.VerifyNone(t)
    myFunc() // should not leak goroutines
}

Kontekst jako rozwiązanie

Idiomaticznym sposobem zatrzymywania długo działających gorutyn jest użycie kontekstu. Należy przekazać ctx do gorutyny i wykonać select na ctx.Done().

go func(ctx context.Context) {
    for {
        select {
        case work := <-workCh:
            process(work)
        case <-ctx.Done():
            return // clean exit
        }
    }
}(ctx)

Wzorzec kanału done

W prostszych przypadkach, gdy nie używa się kontekstu, należy użyć dedykowanego kanału done. Zamknięcie go rozsyła sygnał zatrzymania do wszystkich gorutyn, które z niego odbierają.

done := make(chan struct{})
go func() {
    select {
    case v := <-data: use(v)
    case <-done: return
    }
}()
close(done) // stops goroutine

Wykrywanie za pomocą runtime

Aby wykrywać wzrost liczby gorutyn w czasie działania programu, należy wyświetlać ich liczbę:

fmt.Println("goroutines:", runtime.NumGoroutine())

Gorutyny serwera HTTP

net/http automatycznie zarządza gorutynami dla poszczególnych żądań i sprząta je po zakończeniu żądania. Jednak procedury obsługi, które uruchamiają gorutyny bez ich późniejszego sprzątania, nadal mogą powodować wycieki.

Testowanie wycieków

Należy uruchomić zestaw testów z goleak jako TestMain lub użyć defer dla pojedynczego testu. Każda gorutyna, która nie zakończy się po wykonaniu treści testu, powoduje niepowodzenie testu.

func TestMain(m *testing.M) {
    goleak.VerifyTestMain(m)
}

Wycieki związane z Time.After

time.After w instrukcji select wewnątrz pętli tworzy nowy licznik czasu w każdej iteracji. Nie może on zostać usunięty przez GC, dopóki nie upłynie jego czas. Należy zastąpić go przez time.NewTimer i Reset.

Wyciek spowodowany zwróceniem błędu przez gorutynę

Jeśli gorutyna ma wysłać wynik przez kanał, ale wcześniej kończy działanie z powodu błędu i niczego nie wysyła, gorutyna odbierająca blokuje się na zawsze. Należy zawsze wysłać wartość lub zamknąć kanał na każdej ścieżce wykonania.

Szybki test

Jaki jest najbardziej idiomatyczny sposób zatrzymania długo działającej gorutyny w Go?

Podsumowanie: wykrywanie wycieków i anulowanie

Najważniejsze informacje:

  • Wyciekające gorutyny gromadzą się; ich liczbę można monitorować za pomocą runtime.NumGoroutine()
  • goleak automatycznie wykrywa wycieki gorutyn w testach
  • Gorutynom należy zawsze zapewnić drogę wyjścia: kontekst, kanał done lub zamknięty kanał wejściowy
  • time.After w pętlach powoduje wycieki liczników czasu; należy używać NewTimer+Reset

Często zadawane pytania

Czy lekcja „Wykrywanie wycieków i anulowanie” jest bezpłatna?

Tak — pełny tekst „Wykrywanie wycieków i anulowanie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wykrywanie wycieków i anulowanie”?

Zapewnianie kończenia pracy goroutines i zapobieganie wyciekom Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Wykrywanie wycieków i anulowanie”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wzorce potoków i etapów
  2. errgroup do współbieżnej obsługi błędów
  3. Wzorzec semafora
  4. Wykrywanie wycieków i anulowanie
← Powrót do Go Academy