sábado, 20 de março de 2010

Conceitos de Memoria na JVM



Brincando a noite com Python, fui estudar a fundo a PVM, e a integração Java + Python =Jython!!

Logo, ja estava me aventurando no tema concorrencia, e recordando acerca do modelo de memoria compartilhada do Java, locks, semaforos , STM ,Actors...

Dai relembrei do conceito de Memoria Stack, Heap e onde a threads entram nessa historia.



STACK


Basicamente , na Memoria Stack cada thread(linha de execução) da máquina virtual Java(JVM) tem uma pilha privada da propria JVM, criada ao mesmo tempo que a thread.


Uma JVM(máquina virtual Java) armazena frames de memoria. Ele contém as variáveis locais e resultados parciais, e desempenha um papel na invocação de método e de retorno.

Ja que a JVM Stack não é manipulada diretamente, exceto por push e pop de quadros, quadros tambem podem ser alocados na heap. A memória para uma JVM Stack não precisa ser contígua.

A especificação Java máquina virtual permite que as pilhas da máquina virtual Java ou ter um tamanho fixo ou dinamicamente expandir o contrato de acordo com o exigido pela computação.

Se a JVM Stack tiverem um tamanho fixo, o tamanho de cada JVM Stack pode ser escolhido independentemente quando essa Stack é criada. A implementação da máquina virtual Java pode fornecer ao programador ou ao utilizador o controle do tamanho inicial das pilhas da máquina virtual Java, bem como, no caso de expansão dinamica ou contração das JVMS Stack's, modificando o controle sobre os tamanhos máximos e mínimos.

As seguintes condições excepcionais estão associados com as pilhas da máquina virtual Java:

  • Se o cálculo em um segmento exige um maior JVM Stack do que é permitido, a máquina virtual Java gera um StackOverflowError.
  • Se o tamanho das JVM Stack's pode ser expandido de forma dinâmica, a expansão pode ser feita, mas a memória insuficiente pode ser disponibilizada para o efeito da expansão, ou se a memória insuficiente for disponibilizada para criar a JVM Stack incial de uma thread, a JVM lança um OutOfMemoryError*¹


Heap

A máquina virtual Java tem uma pilha que é compartilhado entre todas as threads da máquina virtual Java. A pilha é a área de dados de tempo de execução a partir do qual a memória de todas as instâncias de classes e arrays são atribuídas.

A Heap(Tipo de Fila de Prioridade) é criada no start da JVM. Um Heap de armazenamento de objetos é recuperado por um sistema automático de gerenciamento de armazenamento (conhecido como um coletor de lixo(garbage collector); objetos nunca são explicitamente liberados*².



A máquina virtual Java não assume qualquer tipo específico de sistema automático de gerenciamento de armazenamento(garbage collector), e a técnica de gerenciamento de armazenamento pode ser escolhida de acordo com os requisitos do implementador do sistema*³.



A Heap pode ser de um tamanho fixo ou pode ser expandida conforme exigido pela computação e pode ser expandido se uma maior pilha torna-se desnecessário. A memória para a Heap não precisa ser contígua.

A pilha de objetos, armazena principalmente objetos ou variáveis de classe.

A seguinte condição excepcional está associado com a Heap:

  • Se um cálculo requer mais memoria Heap do que pode ser disponibilizado pelo sistema automático de gerenciamento de armazenamento, a máquina virtual Java gera um OutOfMemoryError
O tamanho da Heap da JVM pode ser aumentado ou diminuído, conforme necessário: O tamanho da velha geração presente na Heap padrão pode ser substituído usando o Xms-e-Xmx opções para especificar o tamanho inicial e máximo, respectivamente:

java-Xms -Xmx program"> -Xmx codigoQueFazAlgumaCoisa.class -Xmx program">

Por exemplo:

java-Xms64m
-Xmx program">codigoQueFazAlgumaCoisa -Xmx128m

Durante uma de suas palestras e no curso de RubyonRails pela , Fabio Kung deu a seguinte afirmativa baseada em suas analises de como funcionava realmente o modelo de memoria das JVM's : "95% de mortalidade infantil, dentre seus objetos criados", ou seja, a maioria não passa pela etapa de coleta de lixo e são descartados da memoria.

Existem gerações de objetos na Heap e eles são promovidos a areas especificas conforme sobrevivem a coleta de lixo e ganham "idade".


Uma Curiosidade

Assim como campos estaticos(static)são atributos de classe, e não de instancia, podemos usar inicializadores estaticos para definir referencias que necessitem estar presente na construção de objetos mais complexos, ou que são criadas apenas uma vez no ciclo de vidado objeto. Veja o codigo a seguir de tire algumas conclusões!


public class LoadingBlocks {

static{
System.out.println("Inside static");
}

{
System.out.println("Inside init");
}
public static void main(String args[]){
new LoadingBlocks();
new LoadingBlocks();
new LoadingBlocks();
}
}

Output:

Inside static
Inside init
Inside init
Inside init


Seguindo essa logica, poderiamos por exemplo setar um DAO em um objeto de negocios que necessitasse iniciar seu estado atraves do banco de dados na hora de sua construção e isso acontecesse uma unica vez.


public class MeuModeloDeNegocios{
private static MeuModeloDAO;
persistenciaDoMeuModelo;
private List modelos;

static {
persistenciaDoMeuModelo=new MeuModeloDAO();
}

public MeuModeloDeNegocios(){
this.modelos=persistenciaDoMeuModelo.listaTodos();
}
}

Com este codigo seguimos nossas especificações e assim que a classe é posta na memoria pelo ClassLoader nosso bloco de inicialização cria nosso DAO um unica vez, por mais que criemos milhoes de objetos!

Espero ter ajudado! Obirgado pelo seu tempo! []'s

Marcadores:

0 Comentários:

Postar um comentário

Assinar Postar comentários [Atom]

<< Página inicial