Existe um limite para o número de elementos que uma matriz Java pode conter? Se assim for, o que é?
Existe um limite para o número de elementos que uma matriz Java pode conter? Se assim for, o que é?
Respostas:
Não vi a resposta certa, mesmo que seja muito fácil de testar.
Em uma VM HotSpot recente, a resposta correta é Integer.MAX_VALUE - 5. Depois de ir além disso:
public class Foo {
public static void main(String[] args) {
Object[] array = new Object[Integer.MAX_VALUE - 4];
}
}
Você obtém:
Exception in thread "main" java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
MAX_VALUE-2elementos. Isso é independente do que eu aloco, e realmente me pergunto para que a VM pode usar as duas "coisas" (o comprimento não cabe em 2 bytes).
Integer.MAX_VALUE+1, você terá um número inteiro excedente. Os tamanhos de matriz em Java intnão são long; independentemente do tipo de dados que você armazena em sua matriz, bytes ou referências. Strings são apenas referências a objetos.
Integer.MAX_VALUE - 2= 2 147 483 645. O Java aloca com êxito essa matriz se você a executar -Xmx13G. Falha com OutOfMemoryError: Java heap spacese você passar -Xmx12G.
Isso (é claro) é totalmente dependente da VM.
Navegando através do código-fonte do OpenJDK 7 e 8 java.util.ArrayList, .Hashtable, .AbstractCollection, .PriorityQueue, e .Vector, você pode ver esta reivindicação ser repetido:
/** * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
adicionado por Martin Buchholz (Google) em 09/05/2010 ; revisado por Chris Hegarty (Oracle).
Portanto, provavelmente podemos dizer que o número "seguro" máximo seria 2 147 483 639 ( Integer.MAX_VALUE - 8) e "tentativas de alocar matrizes maiores podem resultar em OutOfMemoryError ".
(Sim, a reivindicação autônoma de Buchholz não inclui evidências de apoio, portanto esse é um apelo calculado à autoridade. Mesmo dentro do próprio OpenJDK, podemos ver código como o return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;que mostra que MAX_ARRAY_SIZEainda não tem uso real .)
-8?
-8ocorre devido aos bytes que as palavras reservadas do cabeçalho ocupariam.
Na verdade, existem dois limites. Um, o elemento máximo indexável para a matriz e, dois, a quantidade de memória disponível para seu aplicativo. Dependendo da quantidade de memória disponível e da quantidade usada por outras estruturas de dados, você pode atingir o limite de memória antes de atingir o elemento máximo da matriz endereçável.
Indo por este artigo http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays :
Java tem sido criticada por não apoiar matrizes de mais de 2 31 -1 (cerca de 2,1 mil milhões) elementos. Esta é uma limitação do idioma; a Especificação de Linguagem Java, Seção 10.4, afirma que:
As matrizes devem ser indexadas pelos valores int ... Uma tentativa de acessar um componente da matriz com um valor de índice longo resulta em um erro em tempo de compilação.
O suporte a matrizes grandes também exigiria alterações na JVM. Essa limitação se manifesta em áreas como coleções limitadas a 2 bilhões de elementos e incapacidade de armazenar arquivos de mapas com memória maior que 2 GiB. O Java também não possui matrizes multidimensionais verdadeiras (blocos únicos de memória alocados de forma contígua acessados por um único indireto), o que limita o desempenho da computação científica e técnica.
As matrizes são um número inteiro não negativo indexado; portanto, o tamanho máximo da matriz que você pode acessar seria Integer.MAX_VALUE. A outra coisa é o tamanho da matriz que você pode criar. Depende da memória máxima disponível para o seu JVMe o tipo de conteúdo da matriz. Cada elemento da matriz possui seu tamanho, exemplo. byte = 1 byte, int = 4 bytes,Object reference = 4 bytes (on a 32 bit system)
Portanto, se você tiver 1 MBmemória disponível em sua máquina, poderá alocar uma matriz de byte[1024 * 1024]ou Object[256 * 1024].
Respondendo à sua pergunta - Você pode alocar uma matriz de tamanho (memória / tamanho máximo disponível do item da matriz).
Resumo - Teoricamente, o tamanho máximo de uma matriz será Integer.MAX_VALUE. Praticamente, depende de quanta memória você JVMpossui e de quanto já foi alocado para outros objetos.
Eu tentei criar uma matriz de bytes como esta
byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);
Com esta configuração de execução:
-Xms4G -Xmx4G
E versão java:
Versão do Openjdk "1.8.0_141"
OpenJDK Runtime Environment (compilação 1.8.0_141-b16)
VM do servidor OpenJDK de 64 bits (compilação 25.141-b16, modo misto)
Funciona apenas para x> = 2, o que significa que o tamanho máximo de uma matriz é Inteiro.MAX_VALUE-2
Valores acima que dão
Exceção no encadeamento "main" java.lang.OutOfMemoryError: o tamanho da matriz solicitada excede o limite da VM em Main.main (Main.java:6)
Sim, há limite na matriz java. Java usa um número inteiro como um índice para a matriz e o armazenamento inteiro máximo da JVM é 2 ^ 32. para que você possa armazenar 2.147.483.647 elementos na matriz.
Caso precise de mais do que o tamanho máximo, você pode usar duas matrizes diferentes, mas o método recomendado é armazenar dados em um arquivo. porque armazenar dados no arquivo não tem limite. porque os arquivos são armazenados nos drivers de armazenamento, mas a matriz é armazenada na JVM. A JVM fornece espaço limitado para a execução do programa.
Número máximo de elementos de um arrayé (2^31)−1ou2 147 483 647
Integer.MAX_VALUE - 1, você receberá "java.lang.OutOfMemoryError: o tamanho da matriz solicitada excede o limite da VM". O número máximo de elementos no JDK 6 e acima é Integer.MAX_VALUE - 2= 2 147 483 645. #
Na verdade, é a limitação de java que o limita em 2 ^ 30-4, sendo 1073741820. Não em 2 ^ 31-1. Não sei por que, mas eu testei manualmente no jdk. 2 ^ 30-3 ainda jogando vm, exceto
Edit: corrigido de -1 a -4, verificado no windows jvm