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-2
elementos. 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 int
nã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 space
se 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_SIZE
ainda não tem uso real .)
-8
?
-8
ocorre 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 JVM
e 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 MB
memó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ê JVM
possui 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)−1
ou2 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