September 2008 - Posts
Neste primeiro post sobre GC, você irá compreender seu objetivo e o conceito de gerações.
Enfim o tão esperado Garbage Collector. Apesar de não ser um conceito novo, muitas pessoas desconhecem sua real função e estrutura. Na minha opinião, conhecer o Garbage Collector deveria ser tarefa básica de todos desenvolvedor. Isso mesmo, desenvolvedor! Se o responsável por alocar objetos não conhece o funcionamento deste poderoso recurso, como poderá ter certeza que está tratando a memória e os objetos da melhor maneira possível?
O que é Garbage Collector?
A idéia de Garbage Collector não é nova, e muito menos pertence a uma determinada tecnologia. Em muitas conversas de Java x .NET (uma besteira imensa) já ouvi pessoas dizendo ".NET copiou o GC do Java".
O conceito de garbage collector (GC) nasceu em 1959 por John McCarthy, para resolver problemas do Lisp.
Seu objetivo principal é fornecer um mecanismo automático para gerenciamento de memória, removendo objetos que não serão mais acessados na aplicação. A idéia é deixar a responsabilidade de manter a memória consistente para um mecanismo automático.
Antigamente, esta responsabilidade era do desenvolvedor, que criava a objeto e removia-o da memória.
De cara podemos citar dois problemas:
- O desenvolvedor poderia simplesmente "esquecer" de remover o objeto da memória; ou
- poderia remover o objeto no momento errado, enquanto ainda havia ponteiros para ele.
Esta responsabilidade gerava uma esforço muito grande, o que impactava diretamente no prazo, qualidade e testes de todos os projetos.
Conceito: Heap
O Heap é um gerenciador de memória utilizado para alocar e liberar memória dinamicamente. Normalmente, a utilização do Heap é realizada em situações onde a quantidade de memória necessária é desconhecida, ou muito grande para ser armazenada no stack.
Mecanismo
Existem muitos algoritmos para um Garbage Collector hoje em dia, e todos são dependentes do sistema operacional. Os GC trabalham intimamente com o Gerenciador de Memória do sistema. Por isso, é importante saber que o GC do CLR não é igual ao GC da JVM.
Nestes posts iremos trabalhar apenas com o GC do CLR.
Toda alocação e liberação de memória em uma aplicação .NET é realizada através do Garbage Collector. Por este motivo, o conceito de Managed Heap será aplicado até o fim deste post. O GC gerencia todo o processo de ciclo de vida dos objetos, visando a melhor manutenção da aplicação e tentando evitar problemas de memory leaks, hangs ou crashes.
Quando um processo .NET é iniciado, o sistema operacional aloca um espaço livre de memória, chamado de managed heap. Além disso, o heap mantem um ponteiro de memória chamado NextObjPtr. Este ponteiro indica o local onde o próximo objeto deve ser alocado. A utilização deste ponteiro é básica: quando um novo objeto é criado através da instrução new, é realizada a verificação de espaço para sua alocação. Se existe espaço suficiente, o objeto é criado no endereço apontado pelo NextObjPtr, e este endereço é retornado ao final do construtor.
Ao final deste processo, o NextObjPtr aponta para um novo endereço de memória disponível.
O Managed Heap é dividido em gerações, Gen 0, Gen 1 e Gen 2, além de uma área para objetos grandes (acima de 85Kb). Cada geração desta armazena objetos de "idades" diferentes, do mais novo (Gen 0) para o mais "antigo" (Gen 2). Mas antes, é necessário entender algumas suposições importantes sobre o GC:
- Quanto maior o objeto na memória, maior a probabilidade de ter uma vida mais longa. Essa suposição assume que, quanto maior o objeto, mais trabalho existirá para criá-lo, e programadores vão utilizá-lo quando necessário e por mais tempo, como cache;
- Quanto mais tempo um objeto permanece vivo, a probabilidade de exisitir mais tempo aumenta;
- Todos os objetos são inválidos, até que provem que não.
Por esse motivo as gerações são utilizadas.
| Geração 0 | Este heap é o menor de todos, normalmente com 256Kb. É utilizado para armazenar objetos recem criados. Normalmente os objetos neste geração não passam para as próximas. |
| Geração 1 | Todos os objetos que existiam na Geração 0 e sobrevivem a uma limpeza são "enviados" para a geração 1. Este Heap contém normalmente 2Mb. |
| Geração 2 | Os objetos que continuam existindo após uma limpeza da geração 1 são "enviadas" para a geração 2 (10 Mb). Os objetos deste heap são removidos apenas em uma limpeza total do GC. |
| Large Objects Heap (LOH) | Qualquer objeto maior que 85 Kb será armazenado neste heap, e será removido apenas em uma limpeza total pelo GC. |
Quando o GC inicia um processo de limpeza, todos os objetos da geração 0 que contém alguma raiz são enviados para a geração 1, pois são considerados vivos. Após este processo, a geração 0 fica vazia.
Agora algumas questões que vocês podem estar se perguntando:
Quando uma limpeza ocorre? Quando o GC irá executar?
O GC irá rodar quando uma nova alocação precisa ser realizada e não há espaço suficiente para isso na gen 0. Nesse caso, o GC executa a limpeza na geração 0. Se alocações por conta desta limpeza ocorrem na geração 1 (pelo GC) e também não há espaço, uma limpeza na geração 1 é realizada, e o mesmo ocorre com a geração 2.
IMPORTANTE: Objetos que permanecem vivos depois de uma limpeza sempre vão para a geração seguinte.
LEMBRE-SE: O GC sempre irá limpar apenas a geração 0, sem olhar para objetos com ou sem raiz nas geração seguintes. Isso só irá ocorrer quando a limpeza da geração 0 não liberar espaço suficiente para uma nova alocação.
Outra maneira do GC executar é invocando o método GC.Collect(). Mas isso será um questão para depois. O importante é não utilizar isso, quase nunca!
--
Referências:
http://msdn.microsoft.com/en-us/library/ms973837.aspx
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
http://blogs.msdn.com/tess/archive/2007/04/10/net-garbage-collector-popquiz-followup.aspx
http://grounding.co.za/blogs/brett/archive/2007/07/16/garbage-collection-basics.aspx
Livro Advanced Windows Debugging, de Mario Hewardt e Daniel Pravat;
--
O próximo post irá introduzir conceitos de execução, finalização e dipose, para então partir para WinDBG em Memory Leaks.
Abraços!
Agora sim a parte mais interessante vai começar... tanto que para isso teremos que dividir a parte de análise de memória em diversas partes. E para começar, será necessário introduzir alguns conceitos.
Conceitos Básicos
Esta seção irá apresentar alguns conceitos básicos relacionados ao core do Windows, sem ligação direta e exclusiva com aplicações .NET.
Private Virtual Address Space
Em termos mais simples, private virtual address space é um conjunto de endereços de memória que um determinado processo pode utilizar.
Virtual Memory
Virtual Memory funciona mais ou menos como uma visão simplificada da memória física. Um processo enxerga apenas o seu private virtual address space, de uma maneira linear e organizada. O gerenciador de memória então é o responsável por mapear estes endereços de memória para os endereços físicos de maneira correta.
Mapeamento de memória virtual (esq.) para física (dir.)
A capacidade da memória virtual varia de acordo com a plataforma de hardware. Se fizermos a conta, plataformas 32-bit podem alocar no máximo 4Gb (2^32). Por padrão, o Windows aloca metade deste espaço para utilização do sistema operacional. Portanto, a outra metade apenas é utilizada para outros processos.
E claro, como quase tudo, temos uma saída para mudar estes valores. Em alguns casos, 2 Gb para o sistema operacional pode parecer muito. É possível então especificar o valor de 1Gb para o sistema operacional e 3 Gb para processos, através configuração do boot (Boot.ini). Existe ainda uma outra opção, Address Windowing Extesions, que permite que aplicações 32-bit utilizem 64Gb de memória física em 2Gb de espaço de endereço virtual.
Não vou entrar em detalhes neste post, esta questão está fora do escopo de hoje. Se quiser saber mais informações, entre em contato :)
Em sistemas 64-bit o espaço é muiiiiito maior: 8192Gb de espaço para processos e 6657 para sistema operacional. Digamos que agora não tem do que reclamar :)
Performance Monitor
O famoso perfmon deve ser ferramenta básica para análise de memória. Como estes posts estão relacionados a aplicações .NET, os contadores abaixo serão muito utilizados.
- .NET CLR Memory / # Bytes in all Heaps
- .NET CLR Memory / Large Object Heap Size
- .NET CLR Memory / Gen 2 Heap Size
- .NET CLR Memory / Gen 1 Heap Size
- .NET CLR Memory / Gen 0 Heap Size
- Process / Private Bytes
- Process / Virtual Bytes
Antes de entrarmos nos contadores .NET CLR Memory, vou explicar os dois últimos itens.
Private Bytes se refere ao total em bytes de committed memory de um determinado processo. Já Virtual Bytes se refere ao total do virtual address space para este processo. Mais para frente vamos ver a clara relação destes dois contadores.
Para entrar nos outros contadores será necessário introduzir alguns conceitos de GC, que será realizado no próximo post.
Abraços!
Se você tem curiosidade para saber sobre outros comandos da extensão SOS (SOS.dll), acesse este link:
SOS Debugging Extension (SOS.dll)
http://msdn.microsoft.com/en-us/library/bb190764.aspx
Boa leitura!
Muitas pessoas não sabem por onde começar a aprender Commerce Server 2007. Por isso, estou ministrando um curso de 5 dias, totalmente voltado para o mercado brasileiro e cobrindo todos os tópicos com exemplos e estudos de caso de projetos reais. A próxima turma de 10 pessoas será para Outubro.
Entre em contato para mais informações.
http://www.andrenobre.com.br/treinamentocommerce
Abraços!
Neste quarto post da série vou demonstrar como criar arquivos de Dump.
Conceitos
Um arquivo de Dump representa o estado de um determinado processo. O grande objetivo por trás destes arquivos é possibilitar a análise de problemas sem utilizar o chamado live debugging. Uma vez criado o arquivo, a análise pode ser realizada a qualquer momento e em qualquer máquina*. Este procedimento é muito comum quando equipes distintas trabalham em conjunto para a resolução de hangs ou crashs. Uma equipe responsável pelo processo gera o Dump e outra equipe analisa o arquivo através de WinDBG.
Existem dois tipos de arquivos de Dump, Full e Mini.
O arquivo Full Dump contém todos os dados de memória do processo, o executável, entre outras informações. Já nos arquivos Mini Dump, o conteúdo pode ser variável, dependendo de onde foi gerado.
Nosso foco em todos os posts que envolvem arquivos de Dump será o Mini Dump, e esta opção será detalhada futuramente.
Ferramentas
Nós iremos utilizar a ferramenta Adplus para criar os arquivos de Dump, que já está presente na instalação do Debugging Tools for Windows. O arquivo - um script vbs - se encontra na raiz da instalação.
Adplus é uma ferramenta de linha de comando, criada pela equipe de suporte da Microsoft, para gerar informações sobre qualquer tipo de processo. No exemplo deste post, irei utilizar o adplus para gerar informações para o processo do IIS, ou w3wp.exe. Porém, esta ferramenta pode ser utilizada para qualquer processo, deste Console Applications, Windows Forms, WPF, Services, etc.
Modos de Execução
O Adplus pode ser utilizado de duas maneiras, hang ou crash:
- O modo Hang deve ser utilizado quando o processo apresenta um comportamento estranho ou alta utilização de CPU - nosso popular, "travar". Este modo deve ser executado depois que a aplicação se comportou de forma incorreta.
- O modo Crash deve ser utilizado quando o processo é finalizado inesperadamente. Este modo deve ser acionado antes do processo ser finalizado.
Configuração de ambiente
Para utilizarmos o Adplus corretamente, crie uma variável de ambiente chamada _NT_SYMBOL_PATH, para o caminho c:\symbols (crie esta pasta se não existir). Isto se refere aos símbolos de um processo, o que está fora do escopo deste post. Se você quiser saber mais sobre símbolos agora, acesse http://blogs.msdn.com/tess/archive/2005/12/05/500068.aspx.
Esta configuração não é obrigatória, apenas omite uma mensagem do Adplus, mas será realmente utilizada a partir do próximo post.
Utilização
A demonstração desta ferramenta está neste vídeo (10 minutos).
Conclusão
Este post rápido apresentou como gerar arquivos de Dump e como utilizá-los através do WinDBG. Existem outras maneiras de gerar este tipo de arquivo. Uma maneira muito conhecida é através da ferramenta DebugDiag.
Arquivos de Dump são o padrão para análise de problemas, evitando assim a presença de um profissional capacitado no momento de uma exceção e possibilitando o trabalhando em conjunto com outras equipes.
Espero que vocês tenham gostado deste post, até a próxima.
Links interessantes
http://support.microsoft.com/kb/286350
Abraços.
Neste terceiro post da série (primeiro; segundo), vamos analisar algumas exceções utilizando WinDBG, e como descobrir a origem delas.
Cenário
Para este post criei uma aplicação chamada WinDBGPosts (ASP.NET), que servirá de base para todos os nosso "experimentos". Neste primeiro caso, a aplicação irá gerar exceções em alguns casos, que iremos descobrir através de algumas instruções de WinDBG.
Screencast
Novamente vou demonstrar a utilização do WinDBG através de Screencast.
WinDBG: Analisando Exceções (10 min)
Agora uma questão: se você analisar o stack trace do event viewer e o resultado do !clrstack, verá que os dois são diferentes. Por que?
Abraços!
Há muito tempo eu li em um blog que não me lembro (sorry!) uma opinião que, na época, me chamou a atenção pela falta de educação. O autor dizia que a maioria dos blogs brasileiros eram mais parecidos com bookmarks do que artigos interessantes. A maioria das pessoas usam os blogs para dizer "Ei, achei um texto interessante, acesse...".
Depois de muito tempo tenho que admitir: é verdade.
Abraços.
Apesar de sempre ter trabalho de forma terceirizada (alocado ou não), nunca concordei com este tipo de trabalho. E não falo especificamente sobre os profissionais, mas sim sobre suas vantagens.
A terceirização em todo mundo passou por duas fases. A primeira fase tinha como objetivo a redução de custos através da transferência de responsabilidade pela infra-estrutura. Já a segunda fase teve como objetivo aumentar a produtividade, transferindo a responsabilidade da infra-estrutura e do desenvolvimento de novas aplicações. E é exatamente nesta segunda fase (a que ainda estamos) que se encontram os maiores problemas.
Na minha opinião, se alguém é responsável pela produção, e não por seus resultados, este alguém não irá se preocupar em inovar o mercado, garantir a melhor qualidade, vestir a camisa, se preocupar com repercussões, etc. Claro, a responsabilidade existe, ainda mais pela alta rotatividade no meio em que trabalhamos. Mas vamos concordar... nesta fase de terceirização, existe a responsabilidade de produzir o que foi dito, não de garantir os resultados esperados pela empresa.
E também é exatamente aqui que nasce uma nova: BPO, ou seja, Business Process Outsourcing.
A idéia principal do BPO é transferir para o parceiro processos de negócios completos. Neste momento, o fornecedor também assume a responsabilidade e os riscos de um processo de negócio.
“Não é só a redução de custo. O que interessa mais é inovar os processos para se tornar mais competitivo, diz Carlos Kazuo Tomomitsu, diretor sênior da área de Business Solutions da Sonda Procwork.
“Enquanto num outsourcing de contact center o pagamento é feito com base no número de chamadas atendidas, no BPO esse contrato pode prever a satisfação do cliente ou o número de reclamações respondidas num primeiro chamado”, diz Mauro Peres, country manager da IDC Brasil.
O objetivo final de um novo contrato de BPO é entregar o processo a um parceiro que o faça de maneira mais eficiente.
“BPO não é entrega de commodity. O parceiro precisa não só assumir, como fazer melhor e trazer ganho para o cliente”, diz Fabio Fischer, CEO da TCI, empresa brasileira especializada em BPO.
Uma diferença importanto do BPO para outros tipos de outsourcing é a confiança. O cliente precisa confiar suas informações e seus processos ao parceiro. Afinal, BPO não é body shop!
É muito importante também não terceirizar serviços extremamente críticos e estratégicos. A abordagem de BPO com certeza não trará inúmeros benefícios a estes tipos de processos.
Referência: Artigo "Pronto para o BPO?", de Silvia Balieiro, da Info CORPORATE.
Abraços.
Microsoft SharedView is a fast, easy way to share documents and screen views with small groups of friends or coworkers; anytime, anywhere. Use SharedView to put your heads together and collaborate - create, convey, and communicate…across physical boundaries, through firewalls, and down to the smallest details.
Minha opinião: gostei da idéia, da interface e da facilidade. Mas não gostei da obrigação de ter o acesso a internet e o fato de ter que passar por um servidor do sharedview para compartilhamento. Seria muito melhor se fosse possível criar apresentações para intranets, além de ser muito mais rápido.
http://connect.microsoft.com/site/sitehome.aspx?SiteID=94
Abraços.
-- André
Quando eu li rapidamente sobre o Windows Workflow Foundation eu fiquei impressionado. A interface gráfica, a facilidade, a similaridade com o Biztalk, a produtividade, tudo me chamou a atenção. Mas logo no minuto seguinte eu me perguntei: "Pra quê? Por que eu usuaria o Windows Workflow Foundation ao invés de utilizar uma solução customizada?".
Este post tem o objetivo de apresentar benefícios que o WF (Workflow Foundation) pode trazer às aplicações reais, assim como uma demonstração básica (mas real) da utilização de um workflow e os benefícios aqui apresentados.
Qualquer tipo de projeto é baseado em regras de negócios. Estas regras baseiam-se em definições e operações para atingir um determinado objetivo. Todas as regras são formadas pelo what e pelo how (veja http://en.wikipedia.org/wiki/Business_rules).
QUALQUER regra de negócio pode ser definida em um workflow.
Outro ponto importante sobre regras de negócio é que, no nosso mundo da tecnologia, as regras de negócio mudam. Infelizmente não temos como definir uma regra de negócio e simplesmente assumir que esta regra será desta maneira e pronto. As regras de negócio mudam, e precisamos estar preparados para responder a esta mudança da forma mais rápida possível.
Além disso, regras de negócio podem ser complexas demais. Tanto que alguns projetos em andamento, ou principalmente aqueles que já estão finalizados, existem regras de negócio que só o profissional diretamente envolvido entende. Manutenção? Nem pensar!
Partindo deste cenário, podemos listar algumas características relacionadas com regras de negócio:
- Regras de negócio sempre mudam;
- A complexidade pode trazer sérios problemas para o entendimento e manutenção destas regras;
- Toda regra de negócio pode ser definida em um workflow;
Ok, mas e agora? Como definir em termos arquiteturais algo que atenda estas características?
Aqui entra o Windows Workflow Foundation.
Como você já deve saber, o Windows Workflow Foundation é framework totalmente voltado para construção de workflows de forma rápida, fácil e confiável, além de permitir customização, fornecer segurança, performance e escalabilidade.
Algumas ótimas razões para utilizar WF [PROWF]:
- Fornece um poderoso e flexível framework para a construção de workflows, deixando o tempo para você se preocupar com problemas reais do negócio.
- Permite workflows sequencias ou máquinas de estado (http://en.wikipedia.org/wiki/Finite_state_machine)
- Suporta a habilidade de salvar um workflow e continuar depois.
- É de graça!
Agora a questão é: onde e como utilizar tudo isso?
Se sabemos que workflow está presente nas regras de negócio, e temos um framework poderoso, como utilizar isto para resolver nossos problemas?
Vamos levar este cenário em conta:
- Regras de negócio complexas;
- Equipe média / grande;
- Alto índice de alterações nos requisitos / regras;
Neste cenário, o Windows Workflow Foundation pode ser utilizado para compor as regras de negócio, utilizando métodos atômicos expostos em uma outra camada do projeto:
Claro que em questões arquiteturais esta não é a melhor solução. Este é apenas um exemplo para este post.
Vamos imaginar um fechamento de pedido em um sistema de e-commerce.
Algumas validações básicas são necessárias, referente à dados do cliente, dados de pagamento e entrega. Quando o usuário optar por fechar o pedido, todas as validações devem ser executadas e o resultado final deve ser devolvido para o método chamador.
Fiz um exemplo em ASP.NET + WF, assim como representado na figura acima. O ASP.NET tem o papel de obter as entidades customizadas e enviar para o workflow. A validação dos dados e comunicação com a camada de serviços é feita dentro deste fluxo de trabalho:
1: protected void FecharPedidoButton_Click(object sender, EventArgs e)
2: {
3: // Cria um novo cliente e associa com a Basket
4: Customer cliente = new Customer();
5: cliente.Name = "André Nobre";
6: cliente.Street = "Rua Lorem Ipsum, 99";
7: cliente.Email = "customer@ecommerce.com";
8:
9: // Cria o objeto Basket
10: Basket carrinho = new Basket(cliente);
11: carrinho.LineItems.Add(new LineItem("Televisão LCD 20'"));
12: carrinho.LineItems.Add(new LineItem("Blue-Ray"));
13:
14: // Dictionary que servirá como argumento para o workflow
15: Dictionary<string, object> wfArguments = new Dictionary<string, object>();
16: wfArguments.Add("basket", carrinho);
17: wfArguments.Add("wfResult", WorkflowReturn.Ok);
18:
19: // Instancia o Workflow Runtime
20: WorkflowRuntime wfRuntime = new WorkflowRuntime();
21:
22: // Cria a instancia do workflow para criação do pedido
23: WorkflowInstance wfInstance = wfRuntime.CreateWorkflow(typeof(PurchaseOrderWorkflow), wfArguments);
24:
25: // Adiciona um delegate para o final da execução do workflow
26: wfRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(wfRuntime_WorkflowCompleted);
27:
28: // Inicia o workflow
29: wfInstance.Start();
30: }
Como podem observar, o código é extremamente simples. Os objetos Customer, Basket, LineItem, foram criados de forma fixa, apenas para exemplo.
A figura abaixo representa o workflow criado para a validação dos dados e fechamento do pedido:
Como podem observar, o fluxo é extramemente intuitivo e de fácil manutenção. Cada atividade pode ser alterada, seja seu código ou sua localização, assim como se está ativo ou não.
Portanto, windows workflow foundation é a melhor opção quando trabalhamos nestes tipos de cenário. Com ele, é possível aumentar a produtividade e melhorar desempenhos, além de possibilitar o trabalho com equipes grandes de maneira fácil e simples.
Anexos
http://www.andrenobre.com.br/files/workflowpost.zip
Referência
[PROWF] Pro WF: Windows Workflow in .NET 3.0; BUKOVICS, Bruce; 2007
Abraços!
-- André
More Posts