Java 배열의 최대 크기가 있습니까?


214

Java 배열에 포함될 수있는 요소 수에 제한이 있습니까? 그렇다면 무엇입니까?


5
당신은 잘못된 대답을 받아 들였습니다. 그런 긴 배열을 할당하십시오 (그리고 메모리가 부족하지 않습니다).
maaartinus


답변:


184

테스트하기가 쉽지만 정답을 보지 못했습니다.

최근 HotSpot VM에서 정답은 Integer.MAX_VALUE - 5입니다. 당신이 그것을 넘어 서면 :

public class Foo {
  public static void main(String[] args) {
    Object[] array = new Object[Integer.MAX_VALUE - 4];
  }
}

당신은 얻는다 :

Exception in thread "main" java.lang.OutOfMemoryError:
  Requested array size exceeds VM limit

57
나는 우리가 평범하고 단순히 답변 downvote 기꺼이하지 않는 downvotes의 생각이 더 의미가 없다고 생각 잘못 . 실제로 5 바이트의 차이는 실제로는 중요하지 않습니다. 그러나 사람들이 실제로 작동하는지 확인하려고 시도하지 않고도 "정식 적으로"답변을 기꺼이 제공한다는 점이 우려됩니다. 메모리 한도는 DUH입니다. "당신은 얼마나 많은 포도를 먹을 수 있습니까?" "음, 냉장고에 몇 명이 있는지에 따라 다릅니다."
Kevin Bourrillion

7
5 바이트를 줄 수 없는지 아십니까 ? 이것은 반드시 Java에서 항상 발생하는 것입니까, 아니면 컴퓨터의 메모리 또는 무언가와 관련이있을 수 있습니까?
Taymon

17
@ Kevin Bourrillion : Oracle 1.7.0_07을 사용하여 변경 된 것으로 보입니다 MAX_VALUE-2. 최대 요소 까지 할당 할 수 있습니다. 이것은 내가 할당 한 것과 무관하며 VM이 두 가지 "사물"을 사용할 수있는 것이 정말로 궁금합니다 (길이가 2 바이트에 맞지 않음).
maaartinus

3
@ TomášZato에서 최신 버전을 사용 Integer.MAX_VALUE+1하면 정수 오버플로가 발생합니다. Java의 배열 크기는 int그렇지 않습니다 long. 배열, 바이트 또는 참조에 어떤 데이터 유형을 저장하든 문자열은 단지 객체 참조입니다.
Quit--Anony-Mousse가

8
JDK 6 이상에서 배열의 최대 요소 수는 Integer.MAX_VALUE - 2= 2 147 483 645입니다. Java를 사용하여 이러한 배열을 실행하면 Java가 해당 배열을 성공적으로 할당합니다 -Xmx13G. OutOfMemoryError: Java heap space통과 하면 실패합니다 -Xmx12G.
Alexey Ivanov

127

이것은 물론 VM에 따라 다릅니다.

오픈 JDK 7과 8의 소스 코드를 찾아 java.util.ArrayList, .Hashtable, .AbstractCollection, .PriorityQueue, 그리고 .Vector, 당신이 볼 수있는 주장이 반복되는 :

/**
 * 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;

이것은 Martin Buchholz (Google) 의해 2010 년 5 월 9 일에 추가됨 ; Chris Hegarty (Oracle)에 의해 검토되었습니다.

그래서, 아마도 우리는 최대 "안전한"숫자가 될 것이라고 말할 수 2 147 483 639 ( Integer.MAX_VALUE - 8"더 큰 배열이 될 수 있습니다 할당 시도) 및 OutOfMemoryError를 ".

(이 계산 그래서 예, 벅홀츠의 독립 주장은 증거를 백업에 포함되지 않습니다 권위에 호소. 심지어 오픈 JDK 자체 내에서, 우리는 같은 코드를 볼 수 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;있는 쇼 MAX_ARRAY_SIZE아직없는 실제 사용.)


왜 추가해야 -8합니까?
JohnWinter

@ 페이 서. 이 MAX_ARRAY_SIZE를 ArrayList를 사용할 때만 적용하면 안됩니까? 그것은 int []와 같은 배열을 사용하는 것과 다릅니다. array = new int [some_value_here]; 그렇지 않습니까? ArrayList에 정의 된 상수를 일반 배열 ([]로 정의)에 적용 할 수있는 이유는 무엇입니까? 그들은 무대 뒤에서 동일합니까?
Tiago

1
@Tiago, 아니요. 코드 자체는 최대 크기의 배열과 관련이 없습니다. 그것은 단지 주장입니다.
Pacerier

@JohnWinter, 인용문에는 "일부 VM은 일부 헤더 단어를 배열로 예약합니다"라고 말합니다. 따라서 -8예약 된 헤더 단어가 차지하는 바이트 때문입니다.
Pacerier

38

실제로 두 가지 한계가 있습니다. 하나는 어레이에 대해 색인을 생성 할 수있는 최대 요소이고, 두 개는 애플리케이션에 사용 가능한 메모리 양입니다. 사용 가능한 메모리 양과 다른 데이터 구조에서 사용 된 양에 따라 주소 지정 가능한 최대 배열 요소에 도달하기 전에 메모리 제한에 도달 할 수 있습니다.


27

이 기사로 이동 http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays :

Java는 2 31 -1 (약 21 억 개) 이상의 배열을 지원하지 않는다는 비판을 받았습니다 . 이것은 언어의 한계입니다. Java 언어 사양, 섹션 10.4는 다음을 명시합니다.

배열은 int 값으로 색인화해야합니다 ... 색인 값이 긴 배열 구성 요소에 액세스하려고하면 컴파일 타임 오류가 발생합니다.

큰 어레이를 지원하려면 JVM을 변경해야합니다. 이 제한은 컬렉션이 20 억 요소로 제한되고 2GiB보다 큰 메모리 맵 파일을 사용할 수없는 등의 영역에서 나타납니다. Java에는 과학 및 기술 컴퓨팅의 성능을 제한하는 진정한 다차원 배열 (단일 간접적으로 액세스되는 연속적으로 할당 된 단일 메모리 블록)이 없습니다.


6
Java는 다차원 배열에 대한 구문 설탕이 부족하지만 배열의 전체 크기가 위에서 언급 한 한도를 초과하지 않는 한 약간의 곱셈을 사용하여 "구현"할 수 있습니다.
kbolino

11

배열은 음이 아닌 정수로 색인화되므로 액세스 할 수있는 최대 배열 크기는입니다 Integer.MAX_VALUE. 다른 것은 얼마나 큰 배열을 만들 수 있는지입니다. 사용 가능한 최대 메모리 JVM와 배열의 내용 유형에 따라 다릅니다 . 각 배열 요소의 크기는 예를 들어 있습니다. byte = 1 byte, int = 4 bytes,Object reference = 4 bytes (on a 32 bit system)

따라서 1 MB컴퓨터에 사용 가능한 메모리 가 있으면 byte[1024 * 1024]또는 의 배열을 할당 할 수 Object[256 * 1024]있습니다.

질문에 답하기 -배열의 크기를 할당 할 수 있습니다 (사용 가능한 최대 메모리 / 배열 항목의 크기).

요약 -이론적으로 배열의 최대 크기는입니다 Integer.MAX_VALUE. 실제로 그것은 당신의 메모리 JVM양과 다른 객체에 이미 할당 된 메모리 양에 달려 있습니다.


3

나는 이와 같은 바이트 배열을 만들려 고했다.

byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);

이 실행 구성으로 :

-Xms4G -Xmx4G

그리고 자바 버전 :

Openjdk 버전 "1.8.0_141"

OpenJDK 런타임 환경 (빌드 1.8.0_141-b16)

OpenJDK 64 비트 서버 VM (빌드 25.141-b16, 혼합 모드)

배열의 최대 크기가 정수임을 의미하는 x> = 2에서만 작동합니다 .MAX_VALUE-2

그 이상의 가치

"main"스레드 예외 java.lang.OutOfMemoryError : 요청한 배열 크기가 Main.main (Main.java:6)의 VM 한계를 초과합니다.


2

예, Java 배열에는 제한이 있습니다. Java는 정수를 배열의 인덱스로 사용하며 JVM의 최대 정수 저장소는 2 ^ 32입니다. 따라서 배열에 2,147,483,647 개의 요소를 저장할 수 있습니다.

최대 길이 이상이 필요한 경우 두 개의 다른 배열을 사용할 수 있지만 권장되는 방법은 데이터를 파일에 저장하는 것입니다. 파일에 데이터를 저장하는 데 제한이 없기 때문입니다. 스토리지 드라이버에 저장되지만 배열은 JVM에 저장되기 때문입니다. JVM은 프로그램 실행을위한 제한된 공간을 제공합니다.


1

의 최대 요소 수 array(2^31)−1또는2 147 483 647


5
Java가 size 배열을 할당 할 수 없으면 Integer.MAX_VALUE - 1"java.lang.OutOfMemoryError : 요청한 배열 크기가 VM 제한을 초과합니다"라는 메시지가 표시됩니다. JDK 6 이상의 최대 요소 수는 Integer.MAX_VALUE - 2= 2 147 483 645입니다.
Alexey Ivanov

0

실제로 2 ^ 30-4에서 1073741820으로 제한하는 Java 제한입니다 .2 ^ 31-1이 아닙니다. Dunno 이유는 있지만 jdk에서 수동으로 테스트했습니다. 2 ^ 30-3 여전히 VM을 던지고

편집 : 고정 -1 ~ -4, Windows JVM에서 확인


32 비트 JVM을 사용하고 있습니다. 64 비트 JVM을 사용하면 JVM 한계는 2 ^ 31에 가깝습니다. (사용 가능한 힙 공간도 필요합니다. 이는 기본값이 아니며 실제 메모리의 영향을받습니다.)
dave_thompson_085
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.