none
Consumo de memória RRS feed

  • Pergunta

  • Saudações

    tenho uma aplicação web .net 2 onde o consumo de memória chega a níveis elevados, passando de 200mb e esse valor não diminui, só aumenta.

    Gostaria de saber o que posso fazer para identificar o problema.


    Desenvolva!!!

    terça-feira, 17 de julho de 2012 12:16

Respostas

  • Rodrigo,

    Vou lhe dar um embasamento teórico:

    As classes estáticas para cada chamada geram uma instância (que nada mais é do que uma alocaçao de memória), se todas suas classes são estáticas e em algum devido processamento sao criadas N instancias dessa classe, certamente seu sistema irá alocar mais memória.

    Isso é normal de acontecer, mas para evitar esse tipo de problema é necessário aplicar conceitos de arquitetura.

    Como o Rony citou, o GC (Garbage Collector) não está coletando em tempo suficiente todos objetos da sua Heap.
    Mas eu não recomendo forçar o GC, deixe-o trabalhar da forma dele.

    O que eu lhe recomendo é um Design Pattern muito conhecido como Singleton. Ele reaproveita as instâncias das suas classes estáticas.

    Eu já fiz um sistema que consumia em média 400mb de memória trabalhar com apenas 5mb usando esse Pattern.

    Abaixo um ex de como implementar o Singleton

    using System;
    public sealed class MinhaClasseDAL
    {
        #region " Singleton "
            private static volatile MinhaClasseDAL instance;
            private static object syncRoot = new Object();
            private MinhaClasseDAL() { }
            public static MinhaClasseDAL Instance
            {
                get
                {
                    if (instance == null)
                    {
                        lock (syncRoot)
                        {
                            if (instance == null)
                                instance = new MinhaClasseDAL();
                        }
                    }
                    return instance;
                }
            }
        #endregion
        // Abaixo sua classe segue normalmente
        public void MetodoXPTO
        {
            // TODO: Faz algo.
        }
        
    }


    Você precisa transformar sua classe DAL para ficar nesse aspecto, não tem muito impacto.

    Para chamar seu método estático você fará assim:

    MinhaClasseDal.Instance.MetodoXPTO;

    Sendo assim, se a instancia existir é reutilizada, caso não é criada.

    Faça um teste e nos retorne com o resultado ok?

    Abç...


    É possível sim! Ponha isso na sua cabeça. É possível. "Steve Jobs"

    Eduardo Pires
    www.eduardopires.net.br

           

    terça-feira, 17 de julho de 2012 14:35

Todas as Respostas

  • Você está utilizando classes estáticas?

    Alocando dados pesados tipo dataset em sessions?

    Existe algum tipo de laço de repetição que preencher algum objeto?

    O que sua aplicação faz?


    É possível sim! Ponha isso na sua cabeça. É possível. "Steve Jobs"

    Eduardo Pires
    www.eduardopires.net.br

           

    terça-feira, 17 de julho de 2012 13:03
  • Olá. 

    Sim, toda a camada DAL é estática. Session só é usada uma vez. O sistema gerencia o fluxo de uma empresa do ramo vidreiro, ou seja, basicamente é um ERP. Não vejo nada demais nele, mas é bem extenso, com comandos sql complexos.

    Ela inicia com 40mb em média e daí vai subindo e não desce mais.


    Desenvolva!!!

    terça-feira, 17 de julho de 2012 13:23
  • A Session é usada somente em caso de exception, e chamada em uma tela de erro customizada.

    Desenvolva!!!

    terça-feira, 17 de julho de 2012 13:24
  • Cara vc já tentou desalocar memória?

    Existe uma técnica conhecida como (garbage collector), para desalocar memória. veja o exemplo.

    public class LoginController : Controller, IDisposable
    {
       #region Implementação do IDisposable
            //Implement IDisposable.
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            protected virtual void Dispose(bool disposing)
            {
    
            }
    
            ~LoginController()
            {
                Dispose(false);
            }
    
            public class Derived : EmbaixadorasController
            {
                protected override void Dispose(bool disposing)
                {
                    base.Dispose(disposing);
                }
    
            }
            #endregion
    }

    Da uma iplementada em seu cod e ve como fica!

    att;

    terça-feira, 17 de julho de 2012 13:53
  • Rodrigo,

    Vou lhe dar um embasamento teórico:

    As classes estáticas para cada chamada geram uma instância (que nada mais é do que uma alocaçao de memória), se todas suas classes são estáticas e em algum devido processamento sao criadas N instancias dessa classe, certamente seu sistema irá alocar mais memória.

    Isso é normal de acontecer, mas para evitar esse tipo de problema é necessário aplicar conceitos de arquitetura.

    Como o Rony citou, o GC (Garbage Collector) não está coletando em tempo suficiente todos objetos da sua Heap.
    Mas eu não recomendo forçar o GC, deixe-o trabalhar da forma dele.

    O que eu lhe recomendo é um Design Pattern muito conhecido como Singleton. Ele reaproveita as instâncias das suas classes estáticas.

    Eu já fiz um sistema que consumia em média 400mb de memória trabalhar com apenas 5mb usando esse Pattern.

    Abaixo um ex de como implementar o Singleton

    using System;
    public sealed class MinhaClasseDAL
    {
        #region " Singleton "
            private static volatile MinhaClasseDAL instance;
            private static object syncRoot = new Object();
            private MinhaClasseDAL() { }
            public static MinhaClasseDAL Instance
            {
                get
                {
                    if (instance == null)
                    {
                        lock (syncRoot)
                        {
                            if (instance == null)
                                instance = new MinhaClasseDAL();
                        }
                    }
                    return instance;
                }
            }
        #endregion
        // Abaixo sua classe segue normalmente
        public void MetodoXPTO
        {
            // TODO: Faz algo.
        }
        
    }


    Você precisa transformar sua classe DAL para ficar nesse aspecto, não tem muito impacto.

    Para chamar seu método estático você fará assim:

    MinhaClasseDal.Instance.MetodoXPTO;

    Sendo assim, se a instancia existir é reutilizada, caso não é criada.

    Faça um teste e nos retorne com o resultado ok?

    Abç...


    É possível sim! Ponha isso na sua cabeça. É possível. "Steve Jobs"

    Eduardo Pires
    www.eduardopires.net.br

           

    terça-feira, 17 de julho de 2012 14:35
  • Eduardo, estamos testando e parece ter dado um resultado positivo. Quando terminar eu te falo

    Desenvolva!!!

    terça-feira, 17 de julho de 2012 20:24
  • Que bom!

    Espero você postar aqui... Boa sorte...


    É possível sim! Ponha isso na sua cabeça. É possível. "Steve Jobs"

    Eduardo Pires
    www.eduardopires.net.br

           

    terça-feira, 17 de julho de 2012 20:57
  • Bom dia Eduardo.

    Me esqueci de te perguntar se a classe for estática,  cria-se uma nova instância ao chamá-la, como nos métodos. 


    Desenvolva!!!

    quinta-feira, 19 de julho de 2012 13:05
  • Quando você chama a classe pelo meio MinhaClasse.Instance.MeuMetodo o sistema estará sempre aproveitando alguma instância em memória, caso somente nao encontre uma ele a criará.

    É possível sim! Ponha isso na sua cabeça. É possível. "Steve Jobs"

    Eduardo Pires
    www.eduardopires.net.br

           

    quinta-feira, 19 de julho de 2012 14:24