@onimor

Откуда такое большое потребление оперативной памяти?

Через gRPC пытаюсь отправить на сервер файл частями:
private const int _maxSize = 3 * 1024 * 1024;
private byte[] _part = new byte[_maxSize];
private FileRequest _fileRequest;
 
 private async void UploadFiles(InputFileChangeEventArgs e)
 {
       
        foreach (var file in e.GetMultipleFiles())
        {
            try
            {
 
                using var call = GreeterClient.DownloadFile();
                ShowMessage($"Началась загрузка: {file.Name}",Severity.Normal);
                using (var ms = file.OpenReadStream(file.Size))
                {
 
                    while (ms.Length - ms.Position > 0)
                    {
                        if (ms.Length - ms.Position <= _maxSize)
                            _part = new byte[ms.Length - ms.Position];
 
                        await ms.ReadAsync(_part, 0, _part.Length);
                        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        //отправка не сервер. Google.Protobuf.UnsafeByteOperations.UnsafeWrap Съедает оперативу. хотя он не копирует данные,
                        //в отличии от обычного метода Google.Protobuf.ByteString.CopyFrom, который съедает примерно так же...
                        _fileRequest = new FileRequest { FileName = file.Name, FileBytes = Google.Protobuf.UnsafeByteOperations.UnsafeWrap(_part) };
                        await call.RequestStream.WriteAsync(_fileRequest);
                        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        _fileRequest = null; 
                        
                    }
                    await ms.DisposeAsync();
                }
            
                await call.RequestStream.CompleteAsync();
                var response = await call;
                var status = response.Status;
                ShowMessage(status,Severity.Success);
 
                call.Dispose();
            }
            catch(Exception ex)
            {
                ShowMessage(ex.Message, Severity.Error);
            }
            StateHasChanged();
        }
       
    }

Если оставить код, делящий файл на части - то съедает чуть больше самого файла. Хотя должен же 3мб.
С отправкой на сервер сжирает х10 от размера файла(
Не понимаю почему
  • Вопрос задан
  • 277 просмотров
Пригласить эксперта
Ответы на вопрос 1
MANAB
@MANAB
Разрабатываю на C#: Web, Desktop, Gamedev
1. Не понятно, в каком именно моменте времени проблема. Занимаемая оперативная память увеличилась на 3мб ПОСЛЕ отправки всего файла, В МОМЕНТ отправки файла?
2. То, что съедает чуть больше самого файла - так все правильно, есть же еще память, которая тратится на сопутствующие объекты кода - создание FileRequest, внутри других методов всякие обертки (как для UnsafeWrap). Если по итогам закачки файла память занимаемая увеличилась на 3мб - значит еще Garabge Collector не очистил массив _part
3. Для чего нужно делать
FileBytes = Google.Protobuf.UnsafeByteOperations.UnsafeWrap(_part)
? Ведь итак и так отправляется массив байт? Вроде по описанию там просто объект обертки создается для масива.
4 Ну и сама утечка _part = new byte[ms.Length - ms.Position]; - тут при медленной скорости может создаваться массив несколько раз.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы