.NET Core использует большое количество памяти для кодирования сообщений base64 из базы данных. - PullRequest
0 голосов
/ 27 мая 2019

У меня есть большая база сообщений, которую нужно отправить в другие системы.Размер сообщений в среднем составляет 5-10 Мб, но некоторые больше (50-70 Мб).Мне нужно в base64 кодировать каждое сообщение на диск.Мое приложение использует большой объем памяти, кодирующий сообщения на диск, и я не могу понять, почему.

Что я пробовал: Я прочитал несколько постов, касающихся метода dispose.Я реализовал функцию dispose настолько, насколько смог (через using), чтобы высвободить ресурсы, но я все еще наблюдаю высокое использование памяти (700 МБ +) для моего консольного приложения.

Для простоты явыбрал 10 самых больших файлов из моей базы данных, которые варьируются от 55-75 МБ.При нормальных обстоятельствах приложение будет обрабатывать сообщения 24/7.

Вот как выглядит использование моей памяти при выполнении приведенного ниже кода.Плоская линия указывает на конец обработки больших файлов.Почему эти ресурсы не освобождаются?

live memory usage

Вот снимок моего представления кучи:

object heap view

Вот мой код:

const string sql = "SELECT TOP 10 * FROM [dbo].[OutboundMessages] ORDER BY [Length] DESC";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
    connection.Open();
    using (SqlCommand command = new SqlCommand(sql, connection))
    using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
    {
        if (reader.HasRows)
        {
            while (reader.Read())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    int ordinal = reader.GetOrdinal("FileData");
                    long bytesRead, offset = 0;
                    byte[] buffer = new byte[4096];
                    while ((bytesRead = reader.GetBytes(ordinal, offset, buffer, 0, buffer.Length)) > 0)
                    {
                        offset += bytesRead;
                        stream.Write(buffer, 0, (int)bytesRead);
                    }
                    string file = Guid.NewGuid().ToString().Replace("-", string.Empty);
                    using (StreamWriter writer = new StreamWriter(file))
                    {
                        writer.Write(Convert.ToBase64String(stream.ToArray()));
                    }
                }
            }
        }
    }
}

1 Ответ

1 голос
/ 27 мая 2019

Я решил проблему, записав байты непосредственно в файл, кратный 3 байтам (3 * 1024 = 3072).Теперь моя память процесса остается на стабильном уровне 20 Мб.Запись 3 байта (или кратных) одновременно гарантирует, что base64 не потеряет свой двоичный формат при форматировании текста.

const string sql = "SELECT TOP 10 * FROM [dbo].[OutboundMessages] ORDER BY [Length] DESC";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
    connection.Open();
    using (SqlCommand command = new SqlCommand(sql, connection))
    using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
    {
        if (reader.HasRows)
        {
            while (reader.Read())
            {
                string file = Guid.NewGuid().ToString().Replace("-", string.Empty);
                using (StreamWriter writer = new StreamWriter(file))
                {
                    int ordinal = reader.GetOrdinal("FileData");
                    long bytesRead, offset = 0;
                    byte[] buffer = new byte[3072];
                    while ((bytesRead = reader.GetBytes(ordinal, offset, buffer, 0, buffer.Length)) > 0)
                    {
                        offset += bytesRead;
                        writer.Write(Convert.ToBase64String(buffer));
                    }
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...