Горутина останется в памяти до завершения процесса. Go не умеет принудительно останавливать горутины. Если горутина заблокирована (ждёт канал, мьютекс), сборщик мусора её не "соберёт".
Используйте context с отменой: горутина должна периодически проверять ctx.Done() и выходить. Закрытие канала или вызов cancel() разблокирует ожидающие горутины.
ctx, cancel := context.WithCancel(context.Background())
go func() {
select {
case <-ch:
// work
case <-ctx.Done():
return
}
}()
cancel() // сигнал завершения