Как мне уменьшить использование памяти при передаче файлов на c #?

#c# #file #memory #allocation #transfer

#c# #файл #память #распределение #передача

Вопрос:

У меня есть простое приложение для передачи файлов, написанное на c #, использующее TCP для отправки данных.

Вот как я отправляю файлы:

 Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


        byte[] fileName = Encoding.UTF8.GetBytes(fName); //file name
        byte[] fileData =  new byte[1000*1024];
        byte[] fileNameLen = BitConverter.GetBytes(fileName.Length); //length of file name
        FileStream fs = new FileStream(textBox1.Text, FileMode.Open);            
        try
        {
            clientData = new byte[4   fileName.Length];
        }
        catch (OutOfMemoryException exc)
        {
            MessageBox.Show("Out of memory");
            return;
        }

        fileNameLen.CopyTo(clientData, 0);
        fileName.CopyTo(clientData, 4);
        clientSock.Connect("172.16.12.91", 9050);
        clientSock.Send(clientData, 0, clientData.Length, SocketFlags.None);                       
        progressBar1.Maximum = (int)fs.Length;
        while (true)
        {
            int index = 0;
            while (index < fs.Length)
            {
                int bytesRead = fs.Read(fileData, index, fileData.Length - index);
                if (bytesRead == 0)
                {
                    break;
                }

                index  = bytesRead;
            }
            if (index != 0)
            {
                clientSock.Send(fileData, index, SocketFlags.None);
                if ((progressBar1.Value   (1024 * 1000)) > fs.Length)
                {
                    progressBar1.Value  = ((int)fs.Length - progressBar1.Value);
                }
                else
                    progressBar1.Value  = (1024 * 1000);
            }

            if (index != fileData.Length)
            {
                progressBar1.Value = 0;
                clientSock.Close();
                fs.Close();

                break;

            } 
        }            

    }
  

В taskmanager использование памяти в версии выпуска этого приложения составляет 13 МБ, когда я использую OpenFileDialog, затем увеличивается до 16 МБ, когда оно отправляет данные, а затем остается там. Могу ли я что-нибудь сделать, чтобы уменьшить использование памяти? Или есть хороший инструмент, который я могу использовать для мониторинга общего объема выделяемой памяти в приложении?

И пока мы там, действительно ли 16 МБ — это так много?

Комментарии:

1. 16 МБ — это не так уж и много. И почему вы хотите уменьшить объем памяти? Есть ли какая-либо необходимость? Кажется, это преждевременная оптимизация.

Ответ №1:

16 МБ не кажутся таким уж большим объемом используемой памяти. Вы могли бы использовать встроенный профилировщик Visual Studio, чтобы посмотреть, на что затрачивается наибольшая производительность. Смотрите ссылку ниже для получения дополнительной информации о профилировщике: http://blogs.msdn.com/b/profiler/archive/2009/06/10/write-faster-code-with-vs-2010-profiler.aspx

Ответ №2:

Я заметил, что когда я сворачиваю любое приложение, использование памяти значительно снижается. В конце концов я искал способ воспроизвести этот эффект программно, и вот что я нашел:

 [DllImport("kernel32.dll")]
        public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
        public void ReleaseMemory()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
            }
        }
  

Я не знаю недостатков в использовании этого, но пока что ему удалось сэкономить по крайней мере 13 МБ памяти.

Комментарии:

1. Могу я спросить, почему? Я новичок в этом

2. Вы никогда не захотите принудительно переводить систему в GC, потому что теперь вы вводите ненужную коллекцию объектов. Сборщику мусора должно быть разрешено собирать данные, когда он хочет это сделать. Заставляя это, вы влияете на производительность не только вашего приложения, но и системы, в которой оно выполняется. Позвольте среде выполнения делать свое дело, и пусть она делает это тогда, когда считает это уместным.

3. РЕДАКТИРОВАТЬ: я не рекомендую использовать этот метод (если вам не нужно именно то, что он делает), поскольку он вообще не «уменьшает» память.