1 / 56

Garbage Collector

Garbage Collector. Desenvolvendo aplicações de forma eficiente ! Piza*Ahagon*Sponch Os Lixeiros. Goal. Dicas de como escrever código legível que busque a melhor eficiência do Garbage Collector em termos de throughput, responsividade e etc. Agenda. Conceitos de Garbage Collection

silas
Download Presentation

Garbage Collector

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Garbage Collector Desenvolvendo aplicações de forma eficiente ! Piza*Ahagon*Sponch Os Lixeiros

  2. Goal Dicas de como escrever código legível que busque a melhor eficiência do Garbage Collector em termos de throughput, responsividade e etc ... Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  3. Agenda • Conceitos de Garbage Collection • Dicas de programação • Problemas com finalização • Usando referências de objeto • Evitando Memory Leak • Conclusão Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  4. Agenda • Conceitos de Garbage Collection • Dicas de Programação • Problemas com finalização • Usando referências de objeto • Evitando Memory Leak • Conclusão Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  5. Fundamentos • O GC é uma thread de baixa prioridade que ... Vamos falar sério, você espera mais desta palestra  Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  6. Fundamentos • Encontrar e Coletar objetos não alcançáveis • Não Alcançável = qualquer coisa não transitivamente acessível a partir das raízes da aplicação • Automático e Seguro • O desenvolvedor não interfere ativamente na execução do GC, apenas em sua política de execução. • O GC não interfere na integridade do seu código. • Grande variedade de Atuações • Compactação/ sem compactação. • Algorítmos: Copying, mark-sweep, mark-compact ... • Alocação: Linear, listas ... Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  7. Garbage Collection Geracional • Mantém objetos novos e antigos em espaços geracionais (geração = idade) separados. • Hipótese de Geração Fraca • A maioria dos objetos morre jovem • O GC concentra esforço nos objetos jovens • Precisa manter a rastreabiliade de ponteiros dos objetos antigos para os jovens • Mantém referencia apenas de objetos antigos que apontam para objetos jovens. • Eventualmente coleta os objetos antigos. • Algorítmos diferentes para cada espaço de geração. • Possibilidade de algorítmos mais especializados. • Para objetos jovens se preocupa com a eficiência das alocações. • Para objetos antigos se preocupa com eficiência no gerenciamento de memória. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  8. GC Geracional: Desenho Esquemático Geração Jovem Geração Velha Promoção de Objetos Remembered Set Card Table Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  9. GC Geracional  Conclusões • Para utilizá-lo sua aplicação deve ser desenvolvida com a HI de geração fraca. • O espaço de objetos jovem desperdiça memória, mas utiliza uma área pequena da Heap. • O espaço de objetos antigos é melhor gerenciado, pois utiliza a maior parte da Heap. • Objetos jovens são alocados e desalocados rapidamente e frequentemente. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  10. Mais Conclusões • Objetos antigos são alocados e desalocados mais lentamente, entretanto devido a pouca frequencia isto não gera impacto significativo na aplicação. • Existe uma barreira de escrita na geração velha: apenas uma pequena tabela de alocação e atualizada quando é criada ou deletada uma referência de um objeto antigo a um novo. Isto gera um impacto na performance de curto prazo (pois o GC precisa manter esta tabela), mas a a longo prazo diminui as operações na geração velha, melhorando o throughput da aplicação. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  11. Garbage Collection Incremental • Minimiza pausas na aplicação devido ao trabalho do GC • GC atua ao mesmo tempo que a aplicação. • O GC considera que o grafo de objetos da aplicação é mutante. • O GC precisa ser avisado de todas as mutações no grafo. • Também utiliza uma barreira de escrita (remembered set). • Se apenas a geração velha é incremental, não é necessário manter referências aos objetos jovens. • Não utilize -XX:+UseParallelGCe -XX:+UseParNewGC com este algorítmo. • Medidas de Comparação (-XX:+PrintGCDetails ) : • [GC [DefNew: 2074K->25K(2112K), 0.0050065 secs][Train: 1676K->1633K(63424K), 0.0082112 secs] 3750K->1659K(65536K), 0.0138017 secs] Train (GC Incremental): Tamanho Antes -> Tamanho Depois, tempo da operação • [GC [DefNew: 2049K->2049K(2112K), 0.0003304 secs][Train MSC: 61809K->357K(63424K), 0.3956982 secs] 63859K->394K(65536K), 0.3987650 secs] Train MSC (Full Collection: mark-sweep-compact): Tamanho Antes -> Tamanho Depois, tempo da operação Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  12. Como o GC Trabalha • Alocação • Super Rápida • GCs, não compactados são mais lentos. • Tamanho dos Objetos • Quanto maior mais trabalho para o GC fazer o rastreamento das referencias e dados do objeto. • Atualizações em variáveis de referência • Quanto mais referencias mais overheads, especialmente os incrementais e geracionais. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  13. Agenda • Conceitos de Garbage Collection • Dicas de Programação • Problemas com finalização • Usando referências de objeto • Evitando Memory Leak • Conclusão Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  14. Dicas de programação • Alocação de Objetos • Tamanho de Objetos • Ponteiros Nulos • Chamadas Explícitas ao GC • Dimensionamento das Estruturas de Dados • Pool de Objetos Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  15. Alocação de Objetos • Alocação de Objetos é Muito Rápido ! • 10 instruções nativas de máquina (casos comuns) • Não há barreira de escrita • Não é mais lento que C/C++ • Coleta de Objetos Jovens é muito rápida em GCs Geracionais • Conclusão: • Não tenha medo de alocar pequenos objetos para resultados intermediários. • GC adora objetos pequenos e imutáveis. • GCs Geracionais adoram pequenos objetos de curta duração. • Isso não significa que criar objetos desnecessariamente é saudável. • Bom senso: Quanto mais alocações, mais o GC vai trabalhar. • Criar objetos imutáveis para situações específicas é melhor do que repassá-lo continuamente como variável a várias chamadas de métodos. • Use código claro e simples com mais alocações ao invés de código obscuro com muitas trocas de mensagens entre objetos. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  16. “Grandes” Objetos • Problemas com utilização de “Grandes” Objetos • Alocação cara (por caminhos não “tunados”). • Inicialização de variáveis cara (“Zeroing”). • Podem causar quedas de performance e throughput (veja abaixo). • “Grandes” objetos de vários tamanhos podem causar fragmentação em GCs não compactados. • Devem ser evitados sempre que necessário. • Problema: • O que é um objeto grande ? Faça o menor que puder sem ferir seu modelo de negócios e boas práticas. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  17. Ponteiros Nulos //Terminou a utilização do objeto dont-do-this = null; //Quando terminar de //utilizar a variável • Não é necessário, confie no GC (JIT) • No melhor caso: trabalho desnecessário. • No pior caso: introduz bugs. • Casos Excepcionais • Implementações de ArrayList, ou outras estruturas de dados que o forçam a gerenciar manualmente a memória utilizada. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  18. Chamadas Explícitas ao GC • System.gc(); • Tanto trabalho para “tunar” o GC e esta ação provoca um “stop-the-world full GC”. • Utilize -XX:+DisableExplicitGC • Findbugs pode encontrar as chamadas explícitas. • Único caso permitido em algorítmos de GC distribuído entre chamadas RMI – Acho que não é a sua necessidade ;-) Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  19. Dimensionamento das Estruturas de Dados • Evite re-dimensionamentos desnecessários • Cópia de Arrays, por exemplo, é uma operação crítica para performance. • Pode causar fragmentação do GC. • Aloca o Array duas vezes ArrayList<String> list = new ArrayList<String>(); list.ensureCapacity(1024); • Forma sugerida, seja realista. ArrayList<String> list = new ArrayList<String>(1024); Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  20. Pool de Objetos • É muito ruim ! • Lembremo-nos dos conceitos de GCs Geracionais • Objetos não utilizados no pool são como impostos sem benefícios para o GC. • Mesmo quando não utilizados o GC deve processá-los. • A aplicação não está utilizando, onde está a vantagem ? • Exceções • Pool de Threads • Pool de Conexões • Alguém poderia nomear algum outro ? • Motivo • Estes pools são extremamente caros de serem inicializados • Neste caso, utilize bibliotecas já testadas e padronizadas. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  21. Agenda • Conceitos de Garbage Collection • Dicas de programação • Problemas com finalização • Usando referências de objeto • Evitando Memory Leak • Conclusão Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  22. Finalize [JLS 12.6] • Libera recursos que não são coletados automaticamente pelo GC • Último método executado antes da morte do Objeto. • A especificação não garante em que momento o método será chamado. • Não especifica qual Thread chamará o método finalizador • Não garante ordem Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  23. O que acontece na prática • Implementação do método não trivial e é muito suscetível a erros • Durante a alocação a JVM trata objetos que sobrescrevem o método finalize de forma diferente. • Degrada performance da coleta do objeto pelo GC • São gastos dois ciclos do GC (melhor caso). • Primeiro ciclo identifica os objetos que não são alcançáveis e os coloca em uma fila para a execução do finalizador. • Segundo ciclo é usado para liberar a memória do heap. • SSSe o método finalize já foi executado Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  24. O que mais acontece na prática • Objetos que implementam finalize ficam mais tempo em memória. • Mais pressão sobre o GC. • Aplicação pode terminar e não executar todos os objetos que estão na fila de finalização – Trabalho arriscado e desnecessário . Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  25. Quando usar Finalização? • Necessidade de liberar recursos que são nativos. • Quando o objeto faz chamadas nativas e aloca memória (uma função em C que deve fazer uma chamada malloc) • Tentar garantir que um recurso foi realmente liberado. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  26. Como usar Finalização? • Regra de ouro  Não use ! Mas se precisar saiba que ... • Finalize no Java != Destructor em C++ • Escreva o método finalize usando boas práticas • (Effective Java http://www.amazon.com/Effective-Java-Programming-Language-Guide/dp/0321356683) • Chame o método runFinalizerOnExit das classes RunTime ou System • Objetos que implementam finalize devem conter o menor numero possível de referencias. • Finalização é o quase o mesmo que “chorar pelo leite derramado”, utilize como último suspiro. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  27. Como usar Finalização? class MyObject { private byte[] buffer1; private byte[] buffer2; private native void nativeDispose(); public void dispose() { nativeDispose(); } protected void finalize() throws Throwable{ try { dispose(); } finally { super.finalize(); } } } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  28. Como usar Finalização? class MyObject2 extends MyObject { private byte[] buffer3 = new byte[16 * 1024 * 1024]; } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  29. Como usar Finalização? class MyObject3 { private MyObject obj; private byte[] buffer3 = new byte[16 * 1024 * 1024]; public void dispose() { obj.dispose(); } } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  30. Por Último ... finally { • Utilizar a finalização pode comprometer outros recursos que causam problemas de difícil diagnóstico. • e.g. Sincronização • Antes de utilizar leia: • Bloch Joshua, Effective Java(TM) Programming Language Guide (2nd Edition) - November 9, 2007 • Hans Boehm, POPL 2003 • Hans Boehm, TS-3281, 2005 JavaOneSM conference } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  31. Agenda • Conceitos de Garbage Collection • Dicas de programação • Problemas com finalização • Usando referências de objeto • Evitando Memory Leak • Conclusão Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  32. Referências de Objetos • Propósito • Ganchos de eventos post-mortem, mais flexíveis que finalização. • 3 tipos de referencias • Referencias fracas (Weak) • Referencias leves (Soft) • Referencias fantasma (phantom) • Todas as 3 ajudam o GC a decidir quando uma referência a um objeto não é mais utilizada de forma bastante efetiva. • Através do gerenciamento de uma fila de referencias. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  33. Referências Fracas ref = new WeakReference(obj, rq); Referência Referente Ref obj Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  34. Referências Fracas A referencia foi colocada na fila de referencias GC encontrou o referente “morto” e coletou a referencia Referência Referente Ref obj Fila de Referencias rq Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  35. Referências Fracas • Utilização • Avise-me se o objeto referente for coletado pelo GC • Apenas esta referencia não impede a coleta do objeto pelo GC. • get() retornará • O referente, caso não tenha sido coletado • Null, caso contrário • O objeto referente será coletado pelo GC Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  36. :-o Finalização • É uma forma flexível de se implementar finalização. • Prioriza a finalização do objeto • Objetos não serão considerados para “finalização” • Operação não afetada pela fila de finalização da VM • http://www.devx.com/Java/Article/30192 Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  37. Referências Leves • Utilização • Apenas colete este objeto se houver pressão por memória. • get() retornará • O referente, caso não tenha sido coletado • Null, caso contrário • O referente será coletado pelo GC Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  38. Referências Leves • Cuidado ! Você deve ser um desenvolvedor malicioso para utilizar esta política de referencia. • O que é acessível a partir de cada referencia ? • Quanto é caro para recriar ? • Como tomar decisões se não temos uma pista de quais objetos foram coletados e quando. • OK para caches rápidos e simples. • Mas lembre-se de criar referências fortes para dados que devem ser “persistentes” ou lembrados mais pra frente. Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  39. Referências Fantasma • Utilização • Deixe alguns dados acessíveis depois que o objeto referente tenha sido coletado, para que o desenvolvedor utilize estes dados para limpeza de recursos do objeto. • get() retornará • Null, sempre • O referente não será coletado pelo GC, até que ... • Explicitamente liberado pelo usuário • O objeto referente está inacessível Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  40. Agenda • Conceitos de Garbage Collection • Dicas de programação • Problemas com finalização • Usando referências de objeto • Evitando Memory Leak • Conclusão Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  41. O Que É Memory Leak? • Garbage collector irá coletar todos objetos não alcançáveis • Porém, não coletará os objetos que ainda forem alcançáveis • Memory leak no heap • Objetos que são alcançáveis, mas não utilizados • Retenção não intencional de objetos Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  42. Tipos de Memory Leak • Memory leak “tradicionais” • Fácil identificação • Memória começa a aumentar, aumentar e aumentar • OutOfMemoryError • Memory leak “temporário” • O uso da memória heap fica temporariamente muito grande, depois diminui • Aumento da frequência de coletas Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  43. Fontes de Memory Leak • Objetos em um escopo errado • Listeners • Exceções mudando o fluxo de controle • Falta de gerenciamento de metadados Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  44. Objetos em um escopo errado (1/2) • Abaixo, o array alunos é acessado apenas dentro do método processar() • Não será recuperado enquanto a instância de Sala estiver ativa class Sala { private String[] alunos; public void processar(int tamanho) { if(alunos == null || alunos.length <tamanho) alunos = new String[tamanho]; preencher(alunos); imprimir(alunos); } } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  45. Objetos em um escopo errado (2/2) • Lembre-se • GC geracional adora objetos de vida curta class Sala { public void processar(int tamanho) { String[] alunos = new String[tamanho]; preencher(alunos); imprimir(alunos); } } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  46. Listeners (1/2) • Event Listeners (Swing, AWT, etc) { ImageReader reader = new ImageReader(); cancelButton.addActionListenner(reader); reader.readImage(inputFile); // reader é ainda alcançável tão logo // cancelButton permaneça alcançável } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  47. Listeners (2/2) • Precisamos removê-lo explicitamente • Quando o objeto listener nunca mais for usado • Disparo de exceções pode mudar o fluxo de controle try { ImageReader reader = new ImageReader(); cancelButton.addActionListenner(reader); reader.readImage(inputFile); cancelButton.removeActionListener(reader); }catch ( IOException e) { // Se for gerado por readImage(), reader // não será removido do conjunto de // listeners de cancelButton } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  48. Exceções mudando o fluxo de controle • Sempre use blocos finally ImageReader reader = new ImageReader(); cancelButton.addActionListenner(reader); try { reader.readImage(inputFile); }catch ( IOException e) { ...... } finally { cancelButton.removeActionListener(reader); } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  49. Falta de gerenciamento em Metadados • Algumas vezes, queremos • Rastrear metadados de objetos • Manter separado em um map class ImageManager { private Map<Image,File> map = new HashMap<Image,File>(); public void add(Image image, File file) { ... } public void remove(Image image) { ... } Public File get(Image image) { ... } } Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

  50. Falta de gerenciamento em Metadados • O que acontece se o método remove(image) não for chamado ? • A imagem e o arquivo nunca serão removidos do map • Forma muito comum de memory leak • Nós queremos • Que o map perceba que a chave não é mais alcançável • Apague a respectiva entrada • É exatamente o que WeakHashMapfaz: private Map<Image,File> map = new WeakHashMap<Image,File>(); Créditos para J1 TS-2906: John Coomes, Peter Kessler, Tony Printezis

More Related