0Pricing
Java Academy · บทเรียน

การคอมไพล์ 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 archive

JIT ของ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น
  2. ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง
  3. ตรวจสอบไบต์โค้ดด้วย javap
  4. การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ
← กลับไปที่ Java Academy