ตาม JLS int
อาร์เรย์ควรเติมด้วยศูนย์หลังจากเริ่มต้น อย่างไรก็ตามฉันต้องเผชิญกับสถานการณ์ที่ไม่เป็นอยู่ พฤติกรรมดังกล่าวเกิดขึ้นก่อนใน JDK 7u4 และยังเกิดขึ้นในการอัปเดตทั้งหมดในภายหลัง (ฉันใช้การใช้งาน 64 บิต) รหัสต่อไปนี้แสดงข้อยกเว้น:
public static void main(String[] args) {
int[] a;
int n = 0;
for (int i = 0; i < 100000000; ++i) {
a = new int[10];
for (int f : a)
if (f != 0)
throw new RuntimeException("Array just after allocation: "+ Arrays.toString(a));
Arrays.fill(a, 0);
for (int j = 0; j < a.length; ++j)
a[j] = (n - j)*i;
for (int f : a)
n += f;
}
System.out.println(n);
}
ข้อยกเว้นเกิดขึ้นหลังจาก JVM ทำการคอมไพล์บล็อกโค้ดและไม่เกิดขึ้นกับ-Xint
แฟล็ก นอกจากนี้Arrays.fill(...)
คำสั่ง (เช่นเดียวกับคำสั่งอื่น ๆ ทั้งหมดในรหัสนี้) เป็นสิ่งที่จำเป็นและข้อยกเว้นจะไม่เกิดขึ้นหากไม่มีอยู่ เป็นที่ชัดเจนว่าจุดบกพร่องที่เป็นไปได้นี้ถูกเชื่อมโยงกับการเพิ่มประสิทธิภาพ JVM บางอย่าง มีความคิดเกี่ยวกับเหตุผลของพฤติกรรมดังกล่าวหรือไม่?
อัปเดต:
ฉันเห็นพฤติกรรมนี้บนเซิร์ฟเวอร์ HotSpot 64 บิต VM เวอร์ชัน Java ตั้งแต่ 1.7.0_04 ถึง 1.7.0_10 บน Gentoo Linux, Debian Linux (ทั้งเคอร์เนล 3.0 เวอร์ชัน) และ MacOS Lion ข้อผิดพลาดนี้สามารถทำซ้ำได้โดยใช้รหัสด้านบน ฉันไม่ได้ทดสอบปัญหานี้กับ JDK 32 บิตหรือบน Windows ฉันได้ส่งรายงานข้อบกพร่องไปยัง Oracle แล้ว (รหัสข้อผิดพลาด 7196857) และจะปรากฏในฐานข้อมูลข้อบกพร่องของ Oracle สาธารณะในอีกไม่กี่วัน
อัปเดต:
Oracle เผยแพร่ข้อบกพร่องนี้ที่ฐานข้อมูลข้อผิดพลาดสาธารณะ: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857