Para aqueles que desejam sinalizar isso como duplicado, esta pergunta não está relacionada a nenhuma das perguntas como:
Como calcular o tamanho da memória de um array Java?
Tamanho de memória de matrizes int[] do sistema Java de 32 bits
Em Java, quando uma matriz de primitivos int
é criada:
int[] arr = new int[1000];
A JVM aloca memória para todo o comprimento do array * 4 bytes, ou seja, 4000 bytes após a declaração acima? Não vamos nos preocupar com overheads constantes como cabeçalhos etc.
Meu entendimento é que no caso de tipos numéricos primitivos, por exemplo int
, double
etc., o valor padrão '0' também é um valor válido, portanto precisa de memória. Na verdade, a memória necessária completa deve ser alocada no momento de tais declarações.
Como eu poderia verificar isso?
Vamos ver
Como podemos ver, além das instruções que lidam com a invocação do método em si (ou seja, manipulação de pilha), o código gerado pelo C2 para o
test
método consiste em duas instruções,mov %edx,%eax
eadd $0x123,%eax
. Nenhuma alocação de array, nenhuma zeragem de array.Este é, claro, o cenário mais extremo. Mas demonstra que não há exigência de fazer o que foi escrito literalmente, desde que o comportamento resultante seja compatível.
Além disso, o termo “alocação” é ambíguo. Ele implica em mudar alguma estrutura de dados para registrar que uma região específica da memória não está disponível para outros propósitos. Mas há diferenças em quem compartilha essa estrutura e, portanto, o mesmo ponto de vista sobre o que é alocado.
Pequenas alocações geralmente são feitas em um TLAB que é dedicado a um único thread. Então alocar um pequeno array em um TLAB só faz diferença para aquele thread. Do ponto de vista dos outros threads, a memória daquele TLAB não estava disponível de qualquer forma. Mas mesmo quando um novo TLAB é alocado da memória heap compartilhada por todos os threads, é a memória que é considerada já reservada para o processo JVM do ponto de vista do sistema operacional. Somente quando a JVM expande ou encolhe toda a memória heap, isso afetará o que o sistema operacional reserva para a JVM (que é o que pode ter um impacto em outros processos).
Mas mesmo quando a memória é alocada do sistema operacional, ela não precisa ser apoiada pela memória física. O sistema operacional pode adiar essa operação até o ponto em que a primeira operação de gravação real acontece. Até esse ponto, a memória ainda pode ser considerada toda preenchida com zeros, que é o padrão típico, e o sistema não precisa de memória real para uma região toda preenchida com zeros.
Sim, a JVM aloca toda a memória de uma vez.
Java fará como você diz, e mais uma coisa é que a memória precisa ser contígua. Como os dados do arrar são consecutivos, é necessário alocá-los completamente ao inicializar o array, se não houver memória contígua, out of mem ocorrerá.
Será necessário algum espaço para o array em si, mas será apenas de 4 a 8 bytes.
Por exemplo: alocarei vagas de estacionamento para A para acomodar 100 carros. E alocarei vagas de estacionamento para B para acomodar 50 carros logo atrás de A.
Mesmo que A ainda não tenha todos os 100 carros, preciso saber o tamanho exato de cada carro para calcular com precisão o espaço necessário para 100 carros para estacionar A. O mesmo se aplica a B, que é o próximo depois de A.