java:記憶體池、程序池、執行緒池
記憶體池:
自定義記憶體池的思想通過這個"池"字表露無疑,應用程式可以通過系統的記憶體分配呼叫預先一次性申請適當大小的記憶體作為一個記憶體池,之後應用程式自己對記憶體的分配和釋放則可以通過這個記憶體池來完成。
只有當記憶體池大小需要動態擴充套件時,才需要再呼叫系統的記憶體分配函式,其他時間對記憶體的一切操作都在應用程式的掌控之中。
應用程式自定義的記憶體池根據不同的適用場景又有不同的型別。
從執行緒安全的角度來分:
分為單執行緒記憶體池和多執行緒記憶體池。
單執行緒記憶體池整個生命週期只被一個執行緒使用,因而不需要考慮互斥訪問的問題;
多執行緒記憶體池有可能被多個執行緒共享,因此則需要在每次分配和釋放記憶體時加鎖。
相對而言,單執行緒記憶體池效能更高,而多執行緒記憶體池適用範圍更廣。
從記憶體池可分配記憶體單元大小來分:
分為固定記憶體池和可變記憶體池。
所謂固定記憶體池是指應用程式每次從記憶體池中分配出來的記憶體單元大小事先已經確定,是固定不變的;
而可變記憶體池則每次分配的記憶體單元大小可以按需變化,應用範圍更廣,而效能比固定記憶體池要低。
程序池和執行緒池
程序池和執行緒池性質相似,下面以執行緒池為例進行說明。
既然是“池”,我們很容易聯想到“水池”,在使用水的過程中,水池起到了一個緩衝的作用,避免了頻繁開關水龍頭。
同理,程序池也是通過事先劃分一塊系統資源區域
執行緒池內子程序的數目一般在3~10個之間,子執行緒都執行著相同的程式碼,並具有相同的屬性,如優先順序,PGID等。(一個PID只對應著一個程序,但是一個PGID,TGID和SID可能對應著多個程序) 。
當有新的任務來到時,主程序將通過某種方式選擇程序池中的某一個子程序來為之服務。
相比於動態建立子程序,選擇一個已經存在的子程序的代價顯得小得多。
至於主程序選擇哪個子程序來為新任務服務,則有兩種方法:
1)主程序使用某種演算法來主動選擇子程序。最簡單、最常用的演算法是隨機演算法和 Round Robin (輪流演算法)。
2)主程序和所有子程序通過一個共享的工作佇列來同步,子程序都睡眠在該工作佇列上。當有新的任務到來時,主程序將任務新增到工作佇列中。這將喚醒正在等待任務的子程序,不過只有一個子程序將獲得新任務的“接管權”,它可以從工作佇列中取出任務並執行之,而其他子程序將繼續睡眠在工作佇列上。
當選擇好子程序後,主程序還需要使用某種通知機制來告訴目標子程序有新任務需要處理,並傳遞必要的資料。最簡單的方式是,在父程序和子程序之間預先建立好一條管道,然後通過管道來實現所有的程序間通訊。在父執行緒和子執行緒之間傳遞資料就要簡單得多,因為我們可以把這些資料定義為全域性,那麼它們本身就是被所有執行緒共享的。