官术网_书友最值得收藏!

線程、棧與棧楨

在Java中,Java線程與操作系統一對一綁定,Java虛擬機棧也與操作系統線程棧映射,操作系統線程在Java線程創建時創建。前面介紹-Xss配置虛擬機棧的大小便是指定操作系統線程棧的大小。

我們以Java命令啟動一個Java程序就是啟動一個JVM進程。JVM啟動后會加載類字節碼執行,類的加載過程見本書第三章。程序中main方法是Java程序的入口,JVM會為main方法的執行分配一個線程,叫main線程。如代碼清單1-4所示。

代碼清單1-4 打印main方法所在線程名

public static void main(String[] args) throws IOException {
        // 輸出:main
        System.out.println(Thread.currentThread().getName());
}

我們編寫的Java代碼都會在線程中執行,而在Java中創建Thread對象并調用start方法時,JVM會為其創建一個Java線程,并創建一個操作系統線程,將操作系統線程綁定到Java線程上。HotSpot虛擬機線程start流程如下:

// 第一步:jvm.cpp文件中,JVM_StartThread方法
native_thread = new JavaThread(&thread_entry, sz);
// 第二步: thread.cpp文件中,JavaThread的構建方法
os::create_thread(this, thr_type, stack_sz);
// 第三步:os_linux.cpp文化中,os::create_thread方法
OSThread* osthread = new OSThread(NULL, NULL);
thread->set_osthread(osthread);

雖然Java是一門面向對象的語言,但程序運行依然是基于方法的調用,每個方法對應一個棧楨,方法的調用對應棧楨的入棧和出棧。Java類中每個方法的代碼經過編譯處理后最終變為字節碼指令存儲在Code屬性中,這部分內容會在第二章解析Class文件結構時進行詳解。棧與棧楨的關系如圖1.7所示。

圖1.7 線程、棧與棧楨的關系

在調用Thread對象的start方法時,該線程對應的虛擬機棧的第一個棧楨是run方法。run方法中每調用一個方法就對應一個棧楨的入棧,一個方法只有執行結束才會出棧。方法執行結束包括方法拋出異常結束、return命令返回。

棧的大小是固定的,默認棧大小是1M,可通過-Xss參數配置。因此,從run方法開始,如果調用鏈路過深,如遞歸方法,在棧沒有足夠的空間容納下一個棧楨的入棧時,就會出現StackOverflowError錯誤,同時當前棧被銷毀,當前線程結束。HotSpot虛擬機的實現源碼[1]如代碼清單1-6所示。

代碼清單1-6 HotSpot方法調用源碼

void JavaCalls::call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS) {
  os::os_exception_wrapper(call_helper, result, &method, args, THREAD);
}

void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) {
  methodHandle method = *m;
  JavaThread* thread = (JavaThread*)THREAD;
  .......
   // 判斷當前線程的調用棧是否有足夠的內存
  if (!os::stack_shadow_pages_available(THREAD, method)) {
     // 內存不足,拋出stack_overflow異常
    Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);
    return;
  } else {
    // 占用足夠的內存
    os::bang_stack_shadow_pages();
  }
  ......
}

注釋:

[1] 源碼在hotspot/src/share/vm/runtime/javaCalls.cpp文件中

主站蜘蛛池模板: 抚宁县| 霍城县| 惠水县| 广德县| 泸溪县| 宣汉县| 罗江县| 尼玛县| 鄂温| 唐山市| 哈密市| 故城县| 精河县| 深水埗区| 班戈县| 巴中市| 海伦市| 乌恰县| 新乡市| 绍兴市| 陆良县| 潜江市| 兴城市| 高台县| 武陟县| 青海省| 蒙阴县| 河西区| 三明市| 吕梁市| 内乡县| 基隆市| 漳州市| 钟祥市| 石阡县| 平凉市| 永善县| 西安市| 峨边| 曲周县| 杂多县|