¿Cómo restaurar el uso de memoria de mi programa?

I'm creating app which uses very large amount of memory. When I finish computation the program remains with high memory as I can notice in Task Manager.

How to reset RAM memory usage of my program?

I'm creating a large array in which I store MB worth of random characters. Then print all characters into a variable and then write the content of the variable to the file.

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();
        }
    }
}

preguntado el 31 de enero de 12 a las 08:01

There is little you can do about this. The memory consumed by unused object gets freed when garbage collection happens. And you can not force garbage collection. You can read more about it on MSDN también verifique Clase GC -

4 Respuestas

There is little you can do about this. The memory consumed by unused object gets freed when garbage collection happens. And you can not force garbage collection. You can read more about it on MSDN también verifique Clase GC

Ejemplo de 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();
    }
}

Respondido el 31 de enero de 12 a las 12:01

Types with resources should implement IDisposable, and freeing these resources is done by calling Dispose (or wrapping them in a using statement). GC.Collect is only necessary for objects that have resources but don't implement IDisposable.

Respondido el 31 de enero de 12 a las 12:01

You can't force GC

But if you want to set the memory free as soon as you are done with your array.

//I assume stringChars is the array
stringChars.Clear();
stringChars = null; 
GC.Collect(); 

Respondido el 31 de enero de 12 a las 12:01

It depends on what type of memory you want to be freed. Really calling GC.Collect(); may not work. Why?

  1. It collects objects but you don't know which objects. Your object is large. Usually garbage collectors don't collect large objects or they do it rarely (but rarely for machine time measurement not for human).

  2. It is very likely that virtual memory allocated for your array wouldn't be released to the OS. Because virtual machine memory managers usually reuse freed memory. Also they perform preallocation of memory. They allocate large piece of memory and then use it. It allows not to perform a lot of system calls to get memory for new objects because .NET languages usually create a lot of them (in C++ copying is used a lot and heap is "dummy" in compare with .NET memory manager).

Respondido el 31 de enero de 12 a las 13:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.