มีการ จำกัด จำนวนองค์ประกอบที่อาร์เรย์ 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 -Xmx13G
ประสบความสำเร็จในการจัดสรรเช่นอาร์เรย์ถ้าคุณใช้มันด้วย มันล้มเหลวด้วยถ้าคุณผ่านOutOfMemoryError: Java heap space
-Xmx12G
นี่คือ (ขึ้นอยู่กับ VM) ทั้งหมด
การเรียกดูผ่านรหัสที่มาของ OpenJDK 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-05-09 ; ตรวจสอบโดย Chris Hegarty (Oracle)
ดังนั้น อาจจะ เราสามารถพูดได้ว่าสูงสุดจำนวน "ปลอดภัย" จะเป็น 2 147 483 639 ( Integer.MAX_VALUE - 8
) และ "ความพยายามที่จะจัดสรรอาร์เรย์ขนาดใหญ่อาจส่งผลให้OutOfMemoryError "
(ใช่การอ้างสิทธิ์แบบสแตนด์อโลนของ Buchholz ไม่รวมถึงหลักฐานการสนับสนุนดังนั้นนี่จึงเป็นคำอุทธรณ์ที่มีการคำนวณถึงผู้มีอำนาจแม้ใน OpenJDK เองเราสามารถดูรหัส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 (ประมาณ 2.1 พันล้านองค์ประกอบ) นี่เป็นข้อ จำกัด ของภาษา ข้อกำหนดภาษา Java ส่วน 10.4 ระบุว่า:
อาร์เรย์จะต้องจัดทำดัชนีโดยค่า int ... ความพยายามในการเข้าถึงองค์ประกอบอาร์เรย์ที่มีค่าดัชนียาวทำให้เกิดข้อผิดพลาดในการคอมไพล์เวลา
การสนับสนุนอาร์เรย์ขนาดใหญ่จะต้องมีการเปลี่ยนแปลง JVM ด้วย ข้อ จำกัด นี้แสดงออกในพื้นที่เช่นคอลเลกชันที่ถูก จำกัด องค์ประกอบ 2 พันล้านและไม่สามารถแมปไฟล์หน่วยความจำที่มีขนาดใหญ่กว่า 2 GiB 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 ซึ่งหมายความว่าขนาดสูงสุดของอาร์เรย์คือ Integer.MAX_VALUE-2
ค่าข้างต้นที่ให้
ข้อยกเว้นในเธรด "main" java.lang.OutOfMemoryError: ขนาดอาร์เรย์ที่ร้องขอเกินขีด จำกัด VM ที่ Main.main (Main.java:6)
ใช่มีข้อ จำกัด เกี่ยวกับอาร์เรย์ java Java ใช้จำนวนเต็มเป็นดัชนีไปยังอาร์เรย์และที่เก็บจำนวนเต็มสูงสุดโดย JVM คือ 2 ^ 32 เพื่อให้คุณสามารถเก็บองค์ประกอบ 2,147,483,647 องค์ประกอบในอาร์เรย์
ในกรณีที่คุณต้องการมากกว่าความยาวสูงสุดคุณสามารถใช้สองอาร์เรย์ที่แตกต่างกัน แต่วิธีที่แนะนำคือเก็บข้อมูลไว้ในไฟล์ เนื่องจากการจัดเก็บข้อมูลในไฟล์ไม่มีข้อ จำกัด เนื่องจากไฟล์ที่เก็บไว้ในไดรเวอร์อุปกรณ์เก็บข้อมูลของคุณ แต่อาร์เรย์จะถูกเก็บไว้ใน JVM JVM จัดเตรียมพื้นที่ จำกัด สำหรับการเรียกใช้โปรแกรม
จำนวนองค์ประกอบสูงสุดของ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 ไม่ใช่ 2 ^ 31-1 Dunno ทำไม แต่ฉันทดสอบด้วยตนเองใน jdk 2 ^ 30-3 ยังคงขว้าง vm ยกเว้น
แก้ไข: แก้ไข -1 ถึง -4, ตรวจสอบบน windows jvm