แนวคิดพื้นฐาน
ทุกครั้งที่ thread ทำงานใน Java จะมีการสร้าง Runtime Stack ขึ้นมาเพื่อจัดเก็บข้อมูลระหว่างการทำงานของ thread นั้นๆ
คำสำคัญ
- Stack Frame / Activation Record - แต่ละรายการใน stack เรียกว่าสแต็กเฟรม หรือการเปิดใช้งาน บันทึกข้อมูลของแต่ละเมธอดที่ถูกเรียก
- LIFO (Last In, First Out) - ลำดับการลบออกตรงข้ามกับการสร้าง: เมธอดที่เรียกล่าสุดจะถูกลบออกก่อน
- Thread-local - แต่ละ thread มี stack ของตัวเอง ไม่สามารถเข้าถึง stack ของ thread อื่นได้ (thread-safe)
วงจรชีวิตของ Stack
- Thread เริ่มทำงาน → สร้าง stack ใหม่
- เรียกเมธอด → push stack frame (เก็บพารามิเตอร์ ตัวแปรท้องถิ่น ค่ากลาง ฯลฯ)
- เมธอดทำงานเสร็จ → pop stack frame ออก
- เมธอดทั้งหมดเสร็จ → stack ว่าง → ทำลาย stack → จบ thread
ตัวอย่าง: การจบการทำงานปกติ
public class Demo {
public static void main(String[] args) {
test();
}
public static void test() {
test2();
System.out.println("This is a test method.");
}
public static void test2() {
System.out.println("This is test2 method.");
}
}
Stack trace (เรียกจากบนลงล่าง): main → test → test2 → (กลับ) test2 จบ → test จบ → main จบ → stack ว่าง → thread จบ
ตัวอย่าง: การจบการทำงานผิดปกติ (Exception)
public class Demo {
public static void main(String[] args) {
test();
}
public static void test() {
test2();
System.out.println("This is a test method.");
}
public static void test2() {
System.out.println(45 / 0); // ArithmeticException
System.out.println("This line won't execute");
}
}
ผลลัพธ์ (Stack Trace)
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Demo.test2(Demo.java:14)
at Demo.test(Demo.java:9)
at Demo.main(Demo.java:5)
คำอธิบาย
เมื่อเกิด exception และไม่ได้ catch จะมีการ stack unwinding: JVM pop stack frame ทีละอันจากบนลงล่าง จนกระทั่งหา exception handler (catch block) หรือจนถึง main thread ถ้าไม่มี handler โปรแกรมจะ crash และพิมพ์ stack trace ออกมา
ในตัวอย่าง: test2 โยน exception → ไม่มี catch ใน test2 → pop test2 → ไม่มี catch ใน test → pop test → ไม่มี catch ใน main → โปรแกรมจบแบบผิดปกติ
โครงสร้าง Stack Frame (รายละเอียด)
- Local Variable Array - เก็บตัวแปรท้องถิ่น (parameters + local variables)
- Operand Stack - พื้นที่ทำงานคำนวณชั่วคราว (push/pop operands)
- Frame Data - ข้อมูลคงที่ การอ้างอิง constant pool, exception table, return address