Как восстановить использование памяти моей программой? - PullRequest
0 голосов
/ 31 января 2012

Я создаю приложение, которое использует очень большой объем памяти. Когда я заканчиваю вычисления, программа остается с большим объемом памяти, как я могу заметить в диспетчере задач.

Как сбросить использование оперативной памяти моей программы?

Я создаю большой массив, в котором я храню МБ случайных символов. Затем выведите все символы в переменную, а затем запишите содержимое переменной в файл.

namespace Fake_File_Creator
{
    public partial class MainWindow : Form
    {
        private string text;
        private List<char> stringChars;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnNewFile_Click(object sender, EventArgs e)
        {
            sfdNewFile.Filter = "All Files|*.*";

            if (sfdNewFile.ShowDialog() == DialogResult.OK)
            {
                lblMessage.Text = "Generating data...";
                bwCreateData.RunWorkerAsync((int)nudSize.Value * 1024000);
            }
        }

        private void bwCreateData_DoWork(object sender, DoWorkEventArgs e)
        {
            var random = new Random();
            var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 ~!@#$%^&*()_+ /.,'[];{}|:<>?";

            stringChars = new List<char>();

            for (int i = 0; i < (int)e.Argument; i++)
            {
                stringChars.Add(chars[random.Next(chars.Length)]);
            }

            text = new string(stringChars.ToArray());
        }

        void bwCreateData_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lblMessage.Text = "Saving file...";
            bwCreateFile.RunWorkerAsync();
        }

        private void bwCreateFile_DoWork(object sender, DoWorkEventArgs e)
        {
            using (StreamWriter outfile = new StreamWriter(sfdNewFile.FileName))
            {
                outfile.Write(text);
            }
        }

        void bwCreateFile_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lblMessage.Text = "File succesfully created...";
            text = string.Empty;
            stringChars.Clear();
            stringChars.TrimExcess();
        }
    }
}

Ответы [ 4 ]

4 голосов
/ 31 января 2012

С этим мало что можно сделать.Память, используемая неиспользуемым объектом, освобождается, когда происходит сборка мусора.И вы не можете форсировать сборку мусора.Вы можете узнать больше об этом на MSDN , а также проверить GC Class

Пример из MSDN

private const long maxGarbage = 1000;

static void Main()
{
    MyGCCollectClass myGCCol = new MyGCCollectClass();

    // Determine the maximum number of generations the system
    // garbage collector currently supports.
    Console.WriteLine("The highest generation is {0}", GC.MaxGeneration);

    myGCCol.MakeSomeGarbage();

    // Determine which generation myGCCol object is stored in.
    Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));

    // Determine the best available approximation of the number 
    // of bytes currently allocated in managed memory.
    Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));

    // Perform a collection of generation 0 only.
    GC.Collect(0);

    // Determine which generation myGCCol object is stored in.
    Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));

    Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));

    // Perform a collection of all generations up to and including 2.
    GC.Collect(2);

    // Determine which generation myGCCol object is stored in.
    Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));
    Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));
    Console.Read();
}

void MakeSomeGarbage()
{
    Version vt;
    for(int i = 0; i < maxGarbage; i++)
    {
       // Create objects and release them to fill up memory
       // with unused objects.
       vt = new Version();
    }
}
1 голос
/ 31 января 2012

Вы не можете заставить GC

Но если вы хотите освободить память, как только закончите с вашим массивом.

//I assume stringChars is the array
stringChars.Clear();
stringChars = null; 
GC.Collect(); 
1 голос
/ 31 января 2012

Типы с ресурсами должны реализовывать IDisposable, и освобождение этих ресурсов осуществляется вызовом Dispose (или оборачиванием их в оператор using).GC.Collect необходим только для объектов, которые имеют ресурсы, но не реализуют IDisposable.

0 голосов
/ 31 января 2012

Это зависит от того, какой тип памяти вы хотите освободить.Действительно вызывая GC.Collect ();может не работатьПочему?

  1. Он собирает объекты, но вы не знаете, какие объекты.Ваш объект большой.Обычно сборщики мусора не собирают большие объекты или делают это редко (но редко для измерения машинного времени, а не для человека).

  2. Весьма вероятно, что виртуальная память, выделенная для вашего массива, не будетне будет выпущен в ОС.Поскольку менеджеры памяти виртуальных машин обычно используют освобожденную память.Также они выполняют предварительное распределение памяти.Они выделяют большой кусок памяти и затем используют его.Это позволяет не выполнять много системных вызовов, чтобы получить память для новых объектов, потому что .NET языки обычно создают их много (в С ++ копирование используется очень часто, а куча «пустышка» по сравнению с диспетчером памяти .NET).

...