การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ
เรียนรู้ว่า JVM ตีความเมธอดที่ถูกเรียกใช้บ่อยอย่างไร จากนั้นคอมไพล์ด้วย JIT และเรียนรู้วิธีกระตุ้นพร้อมสังเกตการคอมไพล์
การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
ตัวแปลคำสั่งเทียบกับ JIT
ในระยะแรก JVM จะแปลไบต์โค้ด เมื่อมีการเรียกเมธอดบ่อยครั้ง (เรียกว่า “ร้อน”) คอมไพเลอร์ JIT จะคอมไพล์เมธอดนั้นเป็นโค้ดเครื่องเนทีฟเพื่อให้ทำงานเร็วขึ้นมาก
การคอมไพล์แบบเป็นลำดับขั้น (ค่าเริ่มต้นตั้งแต่ Java 8)
การคอมไพล์แบบเป็นลำดับขั้นใช้ทั้งหมดห้าระดับ: T0 (ตัวแปลคำสั่ง), T1 (C1 แบบง่าย), T2 (C1 เก็บข้อมูลการทำโปรไฟล์แบบจำกัด), T3 (C1 เก็บข้อมูลการทำโปรไฟล์แบบเต็ม), T4 (C2 เพิ่มประสิทธิภาพเต็มรูปแบบ) เมธอดจะเลื่อนขึ้นไปยังระดับที่สูงขึ้นเมื่อมีความร้อนมากขึ้น
// Enable/disable tiered compilation:
// -XX:+TieredCompilation (default ON in Java 8+)
// -XX:-TieredCompilation (disables — only C2 used)คอมไพเลอร์ C1 (คอมไพเลอร์ฝั่งไคลเอ็นต์)
C1 คอมไพล์ได้รวดเร็วพร้อมการเพิ่มประสิทธิภาพในระดับปานกลาง โดยเพิ่มเครื่องมือเก็บข้อมูลการทำโปรไฟล์เพื่อวัดความถี่ในการเรียกและผลลัพธ์ของแขนงสำหรับ C2
คอมไพเลอร์ C2 (คอมไพเลอร์ฝั่งเซิร์ฟเวอร์)
C2 (Opto) ทำการเพิ่มประสิทธิภาพเชิงลึก ได้แก่ การแทรกเมธอด การวิเคราะห์การหลุดออก การคลายลูป การทำเวกเตอร์ และการกำจัดโค้ดที่ไม่ทำงาน ผลลัพธ์คือโค้ดเครื่องเนทีฟที่เร็วที่สุด แต่ใช้เวลาคอมไพล์นานกว่า
// Force server JIT only:
java -server MyApp
// Or explicitly:
java -XX:-TieredCompilation MyApp // uses C2 only (warm-up is slower)เกณฑ์ความร้อน
เมธอดจะถูกคอมไพล์ด้วย JIT หลังจากตัวนับการเรียกข้ามเกณฑ์ที่กำหนด ค่าเริ่มต้นคือ 10,000 ครั้ง (C2) ปรับค่าได้ด้วย -XX:CompileThreshold=N
// Lower threshold for faster warm-up (at cost of less optimization):
java -XX:CompileThreshold=1000 MyAppการแทรกเมธอด
การแทรกเมธอดเป็นการเพิ่มประสิทธิภาพที่ส่งผลมากที่สุดของ C2 โดยเมธอดขนาดเล็กที่ถูกเรียกจากโค้ดร้อนจะถูก “คัดลอกไปวาง” ที่จุดเรียกใช้ เพื่อตัดค่าใช้จ่ายในการกระจายการเรียกเมธอดและเปิดทางให้เพิ่มประสิทธิภาพต่อไป
// Check inlining decisions:
java -XX:+PrintInlining -XX:+UnlockDiagnosticVMOptions MyApp
// Output:
// @ 5 com.example.User::getName (5 bytes) inlinedการวิเคราะห์การหลุดออก
หาก C2 ระบุได้ว่าออบเจ็กต์ไม่เคยหลุดออกจากเมธอด (หรือเธรด) ปัจจุบัน ก็สามารถจัดสรรออบเจ็กต์นั้นบนสแตกแทนฮีพได้ ซึ่งช่วยกำจัดแรงกดดันต่อ GC ได้ทั้งหมด
// Objects that don't escape are stack-allocated:
String result = new StringBuilder().append("Hello ").append(name).toString();
// The StringBuilder may be eliminated by escape analysisบันทึกการคอมไพล์ด้วย JIT
ใช้ -XX:+PrintCompilation เพื่อบันทึกแต่ละเมธอดขณะที่ถูกคอมไพล์ เอาต์พุตจะแสดงชื่อเมธอด ระดับ และแฟล็กการคอมไพล์
// java -XX:+PrintCompilation MyApp
// Output:
// 1 n java.lang.String::hashCode (0 bytes)
// 25 3 com.example.UserService::findById (42 bytes)
// 31 4 com.example.UserService::findById (42 bytes) made not entrantการลดระดับการเพิ่มประสิทธิภาพ
หากสมมติฐานของ JIT ถูกละเมิด (เช่น มีการโหลดคลาสที่เปลี่ยนชนิดของตัวรับที่จุดเรียกใช้) C2 จะ “ลดระดับการเพิ่มประสิทธิภาพ” โดยย้อนกลับไปใช้ตัวแปลคำสั่งหรือ C1 ซึ่งเป็นเรื่องปกติและโดยทั่วไปจะไม่สังเกตเห็น
เวลาอุ่นเครื่อง
การคอมไพล์ด้วย JIT ใช้เวลา ในกระบวนการที่มีอายุสั้น เมธอดอาจไม่ถูกคอมไพล์ด้วย JIT เลย ใช้การคอมไพล์ล่วงหน้า (GraalVM Native Image) หรือแคชผลลัพธ์ JIT ด้วย Class Data Sharing (CDS) เพื่อให้เริ่มทำงานได้เร็วขึ้น
// Enable AppCDS to cache JIT-compilable classes:
java -XX:ArchiveClassesAtExit=app.jsa -cp app.jar MyApp # generate archive
java -XX:SharedArchiveFile=app.jsa -cp app.jar MyApp # use archiveJIT ของ GraalVM
GraalVM แทนที่ C2 ด้วย JIT ที่เขียนด้วย Java ทำให้เพิ่มประสิทธิภาพได้ดีขึ้น ใช้ JIT กับภาษาอื่นที่ไม่ใช่ Java ได้ และเป็นพื้นฐานของ Native Image (การคอมไพล์ล่วงหน้า)
ตรวจสอบอย่างรวดเร็ว
เทคนิคการคอมไพล์ด้วย JIT ใดที่กำจัดค่าใช้จ่ายในการเรียกเมธอดโดยรวมเมธอดขนาดเล็กเข้าไปในเมธอดผู้เรียก
สรุปทบทวน
การคอมไพล์แบบเป็นลำดับขั้นจะเลื่อนเมธอดจาก C1 (คอมไพล์เร็วและเก็บข้อมูลโปรไฟล์) ไปยัง C2 (เพิ่มประสิทธิภาพเชิงลึก) การเพิ่มประสิทธิภาพสำคัญ ได้แก่ การแทรกเมธอด การวิเคราะห์การหลุดออก และการคลายลูป ใช้ -XX:+PrintCompilation เพื่อสังเกตการตัดสินใจของ JIT และอุ่นเครื่องก่อนการเปรียบเทียบประสิทธิภาพ
คำถามที่พบบ่อย
บทเรียน “การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ”
เรียนรู้ว่า JVM ตีความเมธอดที่ถูกเรียกใช้บ่อยอย่างไร จากนั้นคอมไพล์ด้วย JIT และเรียนรู้วิธีกระตุ้นพร้อมสังเกตการคอมไพล์ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น
- ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง
- ตรวจสอบไบต์โค้ดด้วย javap
- การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ