Thread occupying a lot of memory

Asked

Viewed 405 times

1

Come on . I’m loading Buttons into a panel through the Backgroundworker. That is, within this Background I execute a query in the bank through the EF and fill the panel with the Buttons that contain information from this query . The more times the thread runs, the more memory it allocates. What I do to prevent this consumption from growing so much ?

Here is the code of the Backgroundworker

private void WorkCarregaVendas_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        int i = 0;
        while (true)
        {
            Application.DoEvents();
            Application.EnableVisualStyles();
            this.BeginInvoke(new MethodInvoker(() =>
            {
                CarregaVendasAtivas();

                    CarregaMesas();
                    CarregaDeliverys();



                ExecutaPesquisaNumero(txtPesquisaNumero.Text, true);

            }));
         Thread.Sleep(TimeSpan.FromSeconds(30));
        }

    }

Here I press the buttons .

private void CarregaMesas()
    {

        foreach (BotaoOperacional Control in flMesas.Controls)
        {
            Control.Dispose();
        }

        flMesas.Controls.Clear();

        //Pois se há uma pesquisa não a necessidade de carregar todos . 
        if (txtPesquisaNumero.Text.Equals(String.Empty))
            foreach (var mesaCliente in objListaVendasAtivas.Where(x => x.IdTipoVenda == (int)EnumTipoVenda.Mesa).OrderBy(x => x.NumeroMesa))
            {
                decimal preco = 0;
                using (var insRepositorioMesaProduto = new MesaProdutoRepositorio())
                {
                    preco = insRepositorioMesaProduto.
                        PesquisaProdutoMesa(mesaCliente.Id).Select(x => x.Produto)
                        .Sum(x => x.PrecoVenda);
                }
                var btn = new BotaoOperacional(mesaCliente)
                {
                    AtualizarMenuPrincipal = CarregaMesas,
                    Aparencia = EnumTipoVenda.Mesa,
                    NumeroMesa = mesaCliente.NumeroMesa,
                    Cliente = mesaCliente.Cliente == null ? "" : mesaCliente.Cliente.Descricao,
                    Preco = preco
                };



                btn.CarregaBotao();

                flMesas.Controls.Add(btn);


            }

    }
  • Put in the question the code snippet in which you instantiate the buttons from the results of your query. Only then can someone check if by chance you are not leaving buttons allocated from previous queries (which could indicate increased memory consumption).

  • 1

    Luiz already added the code to the question .

  • 1

    Executioner WorkCarregaVendas_DoWork? Because he has an infinite bond (while (true)), if the (apparent) idea would just load the information and end? How do you know that the memory leak is not in the other calls (CarregaVendasAtivas(); or CarregaDeliverys();, for example)? And what does btn.CarregaBotao()? Unfortunately, there are plenty of places where there could be trouble. You tried to restrict the code (commenting) to try to find out where exactly the problem occurs?

  • 1

    as @Luizvieira objected, a while (true) with a Thread.Sleep(TimeSpan.FromSeconds(30)); it doesn’t seem healthy... you could try using a System.Timers.Timer as in the example: https://dotnetfiddle.net/6mkoA5

1 answer

4

Overall

To know where what is causing the unwanted increase in memory consumption, the best thing to do is to run a profile application. It may be that the leak is coming from this thread, it may be that it is coming from elsewhere. Only with an "inside" view to answer.

The process is basically:

  1. Detect which objects unwanted are not being released;
  2. Track the creation points of these objects;
  3. Track the destruction points of these objects;
  4. Track the reference points of these objects.

The (2) is to place breakpoints and see which calls cause the creation of objects, and (3) and (4) are later tracks, see at which points these objects should be destroyed (and are not being) or at which points the objects are being referenced (and should not be). Referenced objects are not destroyed.

using to clear memory

A classic mistake to look at is if you’re using using(){} on all objects that can (or should) be deterministically discarded.

You mentioned that you are using EF. At all points that creates the context object, you are using such a language?

using ( var ef = new SeuContexto() )
{
    ...
}

Normal situation in principle

All that said, what are you watching is the normal. The Garbage Collector does not rotate continuously, and even when it rotates, it is not always that it rotates a version that decreases the apparent program memory.

Gen 2 Collections can be run with several minute differences between each other. That is, the type of GC that low memory only occurs once in a while.

A memory boost is only considered "too" or "problem" when program memory does not stabilize never. The memory rise for several minutes to then fall is more or less the expected behavior.

  • I added the code .

  • The big problem is that when the memory reaches 50 Mb the system generates an Exception (object reference without an object instance).

  • It’s coincidence. Nullpointerexception is usually not memory problem, but code problem. And the code posted does some weird things, Begininvoke endinvole-free, which can drop the application; Call Dispose explicitly (which makes it be called twice in total). NPE you have to debug, or at least record (log in) the exceptions to study later.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.