ฉันคิดว่าคนอื่น ๆ ทำงานได้ดีในการอธิบายว่าทำไม cnt> 0 แต่ไม่มีรายละเอียดเพียงพอเกี่ยวกับสาเหตุที่ cnt = 4 และเหตุใด cnt จึงแตกต่างกันอย่างมากในการตั้งค่าต่างๆ ฉันจะพยายามเติมช่องว่างตรงนี้
ปล่อย
- X คือขนาดสแต็กทั้งหมด
- M คือพื้นที่สแต็กที่ใช้เมื่อเราเข้าสู่หลักในครั้งแรก
- R คือพื้นที่สแต็กที่เพิ่มขึ้นทุกครั้งที่เราเข้าสู่หลัก
- P คือพื้นที่สแต็กที่จำเป็นในการเรียกใช้
System.out.println
เมื่อเราเข้าสู่หลักครั้งแรกพื้นที่ที่เหลือคือ XM การเรียกซ้ำแต่ละครั้งจะใช้หน่วยความจำเพิ่มขึ้น R ดังนั้นสำหรับการเรียกซ้ำ 1 ครั้ง (มากกว่าเดิม 1 ครั้ง) การใช้หน่วยความจำคือ M + R สมมติว่า StackOverflowError ถูกโยนหลังจาก C เรียกซ้ำสำเร็จนั่นคือ M + C * R <= X และ M + C * (R + 1)> X ในช่วงเวลาของ StackOverflowError แรกจะมีหน่วยความจำ X - M - C * R เหลืออยู่
เพื่อให้สามารถเรียกใช้System.out.prinln
งานได้เราต้องการพื้นที่ P จำนวนที่เหลือบนสแต็ก ถ้าเป็นเช่นนั้น X - M - C * R> = P ก็จะพิมพ์ 0 หาก P ต้องการพื้นที่เพิ่มเราจะลบเฟรมออกจากสแต็กโดยได้รับหน่วยความจำ R ในราคา cnt ++
เมื่อprintln
ใดที่สามารถรันได้ในที่สุด X - M - (C - cnt) * R> = P ดังนั้นถ้า P มีขนาดใหญ่สำหรับระบบใดระบบหนึ่ง cnt จะมีขนาดใหญ่
ลองดูตัวอย่างนี้
ตัวอย่างที่ 1:สมมติว่า
- X = 100
- M = 1
- R = 2
- P = 1
จากนั้น C = พื้น ((XM) / R) = 49 และ cnt = เพดาน ((P - (X - M - C * R)) / R) = 0
ตัวอย่างที่ 2:สมมติว่า
- X = 100
- M = 1
- R = 5
- P = 12
จากนั้น C = 19 และ cnt = 2
ตัวอย่างที่ 3:สมมติว่า
- X = 101
- M = 1
- R = 5
- P = 12
จากนั้น C = 20 และ cnt = 3
ตัวอย่างที่ 4:สมมติว่า
- X = 101
- M = 2
- R = 5
- P = 12
จากนั้น C = 19 และ cnt = 2
ดังนั้นเราจะเห็นว่าทั้งระบบ (M, R และ P) และขนาดสแต็ก (X) มีผลต่อ cnt
หมายเหตุด้านข้างไม่สำคัญว่าจะcatch
ต้องใช้พื้นที่เท่าใดในการเริ่มต้น ตราบใดที่ไม่มีพื้นที่เพียงพอสำหรับcatch
cnt ก็จะไม่เพิ่มขึ้นดังนั้นจึงไม่มีผลกระทบภายนอก
แก้ไข
ฉันนำสิ่งที่ฉันพูดถึงcatch
กลับไป มันมีบทบาท สมมติว่ามันต้องใช้พื้นที่จำนวน T เพื่อเริ่มต้น cnt จะเริ่มเพิ่มขึ้นเมื่อพื้นที่ที่เหลือมากกว่า T และprintln
ทำงานเมื่อพื้นที่ที่เหลือมากกว่า T + P ซึ่งจะเพิ่มขั้นตอนพิเศษในการคำนวณและทำให้การวิเคราะห์ที่เป็นโคลนมากขึ้น
แก้ไข
ในที่สุดฉันก็พบว่ามีเวลาทำการทดลองบางอย่างเพื่อสำรองทฤษฎีของฉัน น่าเสียดายที่ทฤษฎีดูเหมือนจะไม่ตรงกับการทดลอง สิ่งที่เกิดขึ้นจริงแตกต่างกันมาก
การตั้งค่าการทดลอง: เซิร์ฟเวอร์ Ubuntu 12.04 ที่มี java เริ่มต้นและ jdk เริ่มต้น Xss เริ่มต้นที่ 70,000 ที่เพิ่มขึ้นทีละ 1 ไบต์จนถึง 460,000
ดูผลลัพธ์ได้ที่: https://www.google.com/fusiontables/DataSource?docid=1xkJhd4s8biLghe6gZbcfUs3vT5MpS_OnscjWDbM
ฉันได้สร้างเวอร์ชันอื่นโดยที่ทุกจุดข้อมูลซ้ำจะถูกลบออก กล่าวอีกนัยหนึ่งจะแสดงเฉพาะจุดที่แตกต่างจากก่อนหน้านี้เท่านั้น ทำให้ง่ายต่อการมองเห็นความผิดปกติ https://www.google.com/fusiontables/DataSource?docid=1XG_SRzrrNasepwZoNHqEAKuZlHiAm9vbEdwfsUA