Baixe o app para aproveitar ainda mais
Prévia do material em texto
Renato Cerqueira Departamento de Informática - PUC-Rio Coletor de Lixo e Referências Fracas Programação Orientada a Objetos Coleta de Lixo em Java • A máquina virtual de Java procura esconder do programador todo o gerenciamento de memória • Não especifica a técnica utilizada – reference counting – mark-and-sweep – ... • Mas nem sempre o gerenciamento automático é o mais conveniente... – problemas de desempenho – memory leaks indesejados Interagindo com o Coletor de Lixo • Classe Runtime – void gc() – void runFinalization() – long freeMemory() – long totalMemory() – long maxMemory() • Uma chamada ao método gc não garante que todo o lixo será coletado Forçando uma coleta completa public static void fullGC() { Runtime rt = Runtime.getRuntime(); //exemplo do pattern singleton long isFree = rt.freeMemory(); long wasFree; do { wasFree = isFree; rt.runFinalization(); rt.gc(); isFree = rt.freeMemory(); }while (isFree > wasFree); } Referências Fracas • Um objeto só pode ser coletado quando não há mais referências para ele no programa (quando ele não é mais “alcançável” • Mas em várias situações gostaríamos que algumas referências específicas não impedissem a coleta de um objeto – caches de objetos – tabelas de associação de atributos a objetos • Referências Fracas: referências especiais que não contam para o coletor de lixo – em Java: reference objects A Classe Abstrata Reference<T> • public T get() – retorna o objeto referenciado • public void clear() – apaga a referência de forma que o objeto Reference em questão não esteja mais associado a outro objeto • public boolean enqueue() – Adiciona o objeto à fila de referências a que está associado, se existir alguma • public boolean isEnqueued() • Obs.: não possui um método de set – as subclasses de Reference definem construtores responsáveis por fazer o binding com o objeto referenciado Subclasses de Reference<T> • SoftReference<T>, WeakReference<T> e PhantomReference<T> • Strongly reachable: objeto alcançável por pelo menos um caminho de referências fortes (refs. convencionais) • Softly reachable: não é strongly reachable mas é alcançável por pelo menos um caminho de refs. leves • Weakly reachable: não é softly reachable mas é alcançável por pelo menos um caminho de refs. fracas • Phantom reachable: não é weakly reachable, já foi finalizado, mas é alcançável por pelo menos um caminho de refs. fantasmas • Unreachable: não é alcançável por nenhum caminho de referências Interação com o Coletor de Lixo • Um objeto que fica weakly reachable (ou menos do que isso), pode ser finalizado • Se depois de sua finalização um objeto é não é mais alcançável, ele pode ser coletado • Os objetos não precisam passar por todos esses estágios • Objetos softly reachable podem ser coletos a critério do coletor de lixo – falte de memória: todas as soft references vão ter sido liberadas antes que uma exceção do tipo OutOfMemoryException seja lançada Interação com o Coletor de Lixo (cont.) • Objetos weakly reachable vão ser coletados pelo coletor de lixo assim que forem identificados – se tornarão finalizáveis e, após finalização, serão coletados, a menos que sejam ressuscitados ou que sejam phantom reachable • Objetos phantom reachable não são realmente alcançáveis pois não é possível obter uma referência através de um PhantomReference (a operação get sempre retorna null) – o objeto já vai ter sido finalizado – só será coletado após a referência fantasma ser explicitamente liberada – referências fantasmas são tipicamente utilizadas em conjunto com filas de referências (references queues) Exemplo import java.lang.ref.*; import java.io.File.*; class DataHandler { private File lastFile; private WeakReference<byte[]> lastData; byte[] readFile (File file) { byte[] data; if (file.equals(lastFile)) { data = lastData.get() if (data != null) return data; } data = readBytesFromFile(file); lastFile = file; lastData = new WeakReference<byte[]> (data); return data; } ... }
Compartilhar