java 面試題 記憶體池 程序池 執行緒池

2021-08-30 02:42:49 字數 1417 閱讀 7393

自定義記憶體池的思想通過這個"池"字表露無疑,應用程式可以通過系統的記憶體分配呼叫預先一次性申請適當大小的記憶體作為乙個記憶體池,之後應用程式自己對記憶體的分配和釋放則可以通過這個記憶體池來完成。

只有當記憶體池大小需要動態擴充套件時,才需要再呼叫系統的記憶體分配函式,其他時間對記憶體的一切操作都在應用程式的掌控之中。

應用程式自定義的記憶體池根據不同的適用場景又有不同的型別。

從執行緒安全的角度來分:

分為單執行緒記憶體池多執行緒記憶體池

單執行緒記憶體池整個生命週期只被乙個執行緒使用,因而不需要考慮互斥訪問的問題;

多執行緒記憶體池有可能被多個執行緒共享,因此則需要在每次分配和釋放記憶體時加鎖。

相對而言,單執行緒記憶體池效能更高,而多執行緒記憶體池適用範圍更廣。

從記憶體池可分配記憶體單元大小來分:

分為固定記憶體池可變記憶體池

所謂固定記憶體池是指應用程式每次從記憶體池中分配出來的記憶體單元大小事先已經確定,是固定不變的;

而可變記憶體池則每次分配的記憶體單元大小可以按需變化,應用範圍更廣,而效能比固定記憶體池要低。

程序池和執行緒池性質相似,下面以執行緒池為例進行說明。

既然是「池」,我們很容易聯想到「水池」,在使用水的過程中,水池起到了乙個緩衝的作用,避免了頻繁開關水龍頭。

同理,程序池也是通過事先劃分一塊系統資源區域,這組資源區域在伺服器啟動時就已經建立和初始化,使用者如果想建立新的程序,可以直接取得資源,從而避免了動態分配資源(這是很耗時的)。

執行緒池內子程序的數目一般在3~10個之間,子執行緒都執行著相同的**,並具有相同的屬性,如優先順序,pgid等。(乙個pid只對應著乙個程序,但是乙個pgid,tgid和sid可能對應著多個程序) 。

當有新的任務來到時,主程序將通過某種方式選擇程序池中的某乙個子程序來為之服務。

相比於動態建立子程序,選擇乙個已經存在的子程序的代價顯得小得多。

至於主程序選擇哪個子程序來為新任務服務,則有兩種方法:

1)主程序使用某種演算法來主動選擇子程序。最簡單、最常用的演算法是隨機演算法和 round robin (輪流演算法)。

2)主程序和所有子程序通過乙個共享的工作佇列來同步,子程序都睡眠在該工作佇列上。當有新的任務到來時,主程序將任務新增到工作佇列中。這將喚醒正在等待任務的子程序,不過只有乙個子程序將獲得新任務的「接管權」,它可以從工作佇列中取出任務並執行之,而其他子程序將繼續睡眠在工作佇列上。

當選擇好子程序後,主程序還需要使用某種通知機制來告訴目標子程序有新任務需要處理,並傳遞必要的資料。最簡單的方式是,在父程序和子程序之間預先建立好一條管道,然後通過管道來實現所有的程序間通訊。在父執行緒和子執行緒之間傳遞資料就要簡單得多,因為我們可以把這些資料定義為全域性,那麼它們本身就是被所有執行緒共享的。

參考:

記憶體池,程序池,執行緒池

在使用new malloc在堆區申請一塊記憶體的時候,由於每次申請的記憶體大小不一樣就會產生很多記憶體碎片,不好管理和浪費。記憶體池則是在真正使用記憶體之前,先申請分配一定數量的 大小相等的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊不夠用再 繼續申請新的記憶...

記憶體池 執行緒池 程序池

由於伺服器的硬體資源 充裕 那麼提高伺服器效能的乙個很直接的方法就是以空間換時間,即 浪費 伺服器的硬體資源,以換取其執行效率。這就是池的概念。池是一組資源的集合,這組資源在伺服器啟動之初就完全被建立並初始化,這稱為靜態資源分配。當伺服器進入正式執行階段,即開始處理客戶請求的時候,如果它需要相關的資...

記憶體池 執行緒池 程序池

首先介紹乙個概念 池化技術 池化技術就是 提前儲存大量的資源,以備不時之需以及重複使用 池化技術應用廣泛,如記憶體池,執行緒池,連線池等等。記憶體池相關的內容,建議看看 apache nginx 等開源web 伺服器的記憶體池實現。由於在實際應用當做,分配記憶體 建立程序 執行緒都會設計到一些系統呼...