Pergunta

Esta questão é para a linguagem Java em particular. Eu entendo que há uma protion estática do conjunto de memória de lado por todo o código estático.

A minha pergunta é como isso é memória estática preenchido? É um objeto estático colocado em memória estática na importação ou na primeira referência? Além disso, fazer as mesmas regras de coleta de lixo aplica a objetos estáticos como eles fazem para todos os outros objetos?


public class Example{
    public static SomeObject someO = new SomeObject();
}
/********************************/
// Is the static object put into static memory at this point?
import somepackage.Example;

public class MainApp{
    public static void main( Sting args[] ){
// Or is the static object put into memory at first reference?
       Example.someO.someMethod();
// Do the same garbage collection rules apply to a 
//     static object as they do all others?
       Example.someO = null;
       System.gc();
    }
}
Foi útil?

Solução

As importações não se correlacionam com quaisquer instruções no código compilado. Eles estabelecem aliases para uso em apenas tempo de compilação.

Existem alguns métodos reflexivas que permitem que a classe a ser carregado, mas ainda não inicializado, mas na maioria dos casos, você pode assumir que sempre que uma classe é referenciado, ele foi inicializado.

initializers Membro estático e blocos estáticos são executados como se todos fossem um só estática initializer bloco, a fim de código-fonte.

Um objeto referenciado através de uma variável membro estático está fortemente referenciada até que a classe é descarregado. A ClassLoader normal, não descarrega uma classe, mas aqueles usados ??por servidores de aplicativos fazer sob as condições certas. No entanto, é uma área complicada e tem sido a fonte de muitos difíceis de diagnosticar vazamentos-contudo memória outra razão para não usar variáveis ??globais.


Como um bônus (tangencial), aqui está uma pergunta complicada a considerar:

public class Foo {
  private static Foo instance = new Foo();
  private static final int DELTA = 6;
  private static int BASE = 7;
  private int x;
  private Foo() {
    x = BASE + DELTA;
  }
  public static void main(String... argv) {
    System.out.println(Foo.instance.x);
  }
}

O que isso vai imprimir o código? Experimente, e você vai ver que ele imprime "6". Há algumas coisas no trabalho aqui, e um é da ordem de inicialização estática. O código é executado como se tivesse sido escrito assim:

public class Foo {
  private static Foo instance;
  private static final int DELTA = 6;
  private static int BASE;
  static {
    instance = null;
    BASE = 0;
    instance = new Foo(); /* BASE is 0 when instance.x is computed. */
    BASE = 7;
  }
  private int x;
  private Foo() {
    x = BASE + 6; /* "6" is inlined, because it's a constant. */
  }
}

Outras dicas

Normalmente, não há tal coisa como memória "estático". A maioria do vm tem a geração permanente da pilha (onde as aulas são carregados), que normalmente não é lixo coletado.

Objetos estáticos são alocados como qualquer outro objeto. Mas, se eles vivem por muito tempo eles vão ser movidos entre as diferentes gerações no coletor de lixo. Mas eles não vão acabar em permgenspace.

Se a sua classe é agarrada este objeto permanentemente, ele só será liberada quando as saídas vm.

Esta variável estática some0 é inicializado assim que sua classe é referenciada em seu código. No seu exemplo este será executado em primeira linha do seu método principal.

Você pode validar isso criando um estática initializer bloco. Coloque um ponto de ruptura neste bloco inicializador e você vai ver, quando ele será chamado. Ou ainda mais simplier ... colocar um ponto de interrupção no construtor de SomeObject.

A inicialização de variáveis ??estáticas são tratadas na secção 2.11 estáticos Initializers de sóis JVM spec. A especificação não define a implementação de coleta de lixo no entanto então eu imagino que as regras de coleta de lixo para objetos estáticos irá variar dependendo da sua VM.

Deve notar-se, que somente o ponteiro (ou qualquer outro tipo primitivo) é armazenado no PermGenSpace (que é o nome apropriado para a área onde o material estático é armazenado).

Assim, o objeto referenciado pelo ponteiro se senta na pilha normal, como qualquer outro objeto.

Se o campo estático é alterado para fazer referência a um objeto diferente, o objeto original apontado pelo campo estático é elegível para o GC, tal como qualquer outro objeto.

Ele também poderia ser free'ed (mesmo que não seja anulado) se a própria classe é descarregado e todo o gráfico do objeto é cortado do heap. Claro que, quando uma classe pode ser descarregado é um bom tema para uma série de outras perguntas ...:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top