Java 배열에 포함될 수있는 요소 수에 제한이 있습니까? 그렇다면 무엇입니까?
Java 배열에 포함될 수있는 요소 수에 제한이 있습니까? 그렇다면 무엇입니까?
답변:
테스트하기가 쉽지만 정답을 보지 못했습니다.
최근 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
MAX_VALUE-2
. 최대 요소 까지 할당 할 수 있습니다. 이것은 내가 할당 한 것과 무관하며 VM이 두 가지 "사물"을 사용할 수있는 것이 정말로 궁금합니다 (길이가 2 바이트에 맞지 않음).
Integer.MAX_VALUE+1
하면 정수 오버플로가 발생합니다. Java의 배열 크기는 int
그렇지 않습니다 long
. 배열, 바이트 또는 참조에 어떤 데이터 유형을 저장하든 문자열은 단지 객체 참조입니다.
Integer.MAX_VALUE - 2
= 2 147 483 645입니다. Java를 사용하여 이러한 배열을 실행하면 Java가 해당 배열을 성공적으로 할당합니다 -Xmx13G
. OutOfMemoryError: Java heap space
통과 하면 실패합니다 -Xmx12G
.
이것은 물론 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
합니까?
-8
예약 된 헤더 단어가 차지하는 바이트 때문입니다.
이 기사로 이동 http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays :
Java는 2 31 -1 (약 21 억 개) 이상의 배열을 지원하지 않는다는 비판을 받았습니다 . 이것은 언어의 한계입니다. Java 언어 사양, 섹션 10.4는 다음을 명시합니다.
배열은 int 값으로 색인화해야합니다 ... 색인 값이 긴 배열 구성 요소에 액세스하려고하면 컴파일 타임 오류가 발생합니다.
큰 어레이를 지원하려면 JVM을 변경해야합니다. 이 제한은 컬렉션이 20 억 요소로 제한되고 2GiB보다 큰 메모리 맵 파일을 사용할 수없는 등의 영역에서 나타납니다. Java에는 과학 및 기술 컴퓨팅의 성능을 제한하는 진정한 다차원 배열 (단일 간접적으로 액세스되는 연속적으로 할당 된 단일 메모리 블록)이 없습니다.
배열은 음이 아닌 정수로 색인화되므로 액세스 할 수있는 최대 배열 크기는입니다 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
양과 다른 객체에 이미 할당 된 메모리 양에 달려 있습니다.
나는 이와 같은 바이트 배열을 만들려 고했다.
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 한계를 초과합니다.
의 최대 요소 수 array
는 (2^31)−1
또는2 147 483 647
Integer.MAX_VALUE - 1
"java.lang.OutOfMemoryError : 요청한 배열 크기가 VM 제한을 초과합니다"라는 메시지가 표시됩니다. JDK 6 이상의 최대 요소 수는 Integer.MAX_VALUE - 2
= 2 147 483 645입니다.
실제로 2 ^ 30-4에서 1073741820으로 제한하는 Java 제한입니다 .2 ^ 31-1이 아닙니다. Dunno 이유는 있지만 jdk에서 수동으로 테스트했습니다. 2 ^ 30-3 여전히 VM을 던지고
편집 : 고정 -1 ~ -4, Windows JVM에서 확인