. NET Core GCP PublisherClient утечка памяти - PullRequest
0 голосов
/ 28 апреля 2020

Я думаю, что столкнулся с возможной утечкой памяти при реализации GCP PubSub PublisherClient в. NET Core. Я написал «Я думаю», потому что, если честно, я даже не уверен, что правильно его использую (и именно поэтому я публикую этот вопрос здесь).

Приложение представляет собой. NET Базовый веб-API. Вот выдержка из реализации, которую я имею:

public class GoogleTopicPublisher : IAsyncDisposable
    {
        private readonly TopicName _topic;
        private readonly string _apiToken;
        private readonly ILogger<GoogleTopicPublisher> _logger;
        private readonly Lazy<Task<PublisherClient>> _lazyPublisher;

        public GoogleTopicPublisher(string projectId, string topicId, string apiToken,
            ILogger<GoogleTopicPublisher> logger)
        {
            _apiToken = apiToken;
            _topic = new TopicName(projectId, topicId);
            _logger = logger;

            _lazyPublisher = new Lazy<Task<PublisherClient>>(() => PublisherClient.CreateAsync(_topic));
        }

        public async Task PublishAsync(PubSubEnvelope envelope)
        { 
            var messageData = Newtonsoft.Json.JsonConvert.SerializeObject(envelope);

            var message = new PubsubMessage()
            {
                Data = ByteString.CopyFromUtf8(messageData),
                Attributes =
                    {
                        {"token", _apiToken }
                    }
            };

            var publisher = await _lazyPublisher.Value;
            await publisher.PublishAsync(message);

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        public async ValueTask DisposeAsync()
        {
            if (!_lazyPublisher.IsValueCreated)
                return;

            var publisher = _lazyPublisher.Value.Result;
            await publisher.ShutdownAsync(TimeSpan.FromSeconds(15));
        }
    }

Весь класс GoogleTopicPublisher зарегистрирован как Singleton. Как вы можете видеть, я создаю экземпляр Publisher с помощью asyn c Lazy, чтобы избежать создания нового экземпляра каждый раз, когда мне нужно опубликовать sh сообщение.

Болевая точка - это вызовы к G C: без них я вижу рост и увеличение использования памяти, пока все приложение не исчерпает память и не будет перезапущено.

Теперь мои вопросы:

  • это хорошая практика для создания экземпляра PublisherClient таким образом? Если нет, есть ли лучший способ?
  • могу ли я каким-либо образом избежать звонков в G C?

спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...