常見池化技術


在系統開發過程中,我們經常會用到池化技術來減少系統消耗,提升系統性能。對象池通過復用對象來減少創建對象、垃圾回收的開銷;連接池(數據庫連接池、Redis連接池和HTTP連接池等)通過復用TCP連接來減少創建和釋放連接的時間。線程池通過復用線程提升性能。簡單來說,池化技術就是通過復用來提升性能。

線程、內存、數據庫的連接對象都是資源,在程序中,當你創建一個線程或者在堆上申請一塊內存的時候都涉及到很多的系統調用,也是非常消耗CPU的。如果你的程序需要很多類似的工作線程或者需要頻繁地申請釋放小塊內存,在沒有對這方面進行優化的情況下,這部分代碼很可能會成為影響你整個程序性能的瓶頸。

線程池

線程池的原理很簡單,類似於操作系統中的緩沖區的概念。線程池中會先啟動若干數量的線程,這些線程都處於睡眠狀態。當客戶端有一個新的請求時,就會喚醒線程池中的某一個睡眠的線程,讓它來處理客戶端的這個請求,當處理完這個請求之后,線程又處於睡眠的狀態。

線程池能很高地提升程序的性能。比如有一個省級數據大集中的銀行網絡中心,高峰期每秒的客戶端請求並發數超過100,如果為每個客戶端請求創建一個新的線程的話,那耗費的CPU時間和內存都是十分驚人的,如果采用一個擁有200個線程的線程池,那將會節約大量的系統資源,使得更多的CPU時間和內存用來處理實際的商業應用,而不是頻繁的線程創建和銷毀。

內存池

如何更好地管理應用程序內存的使用,同時提高內存使用的頻率,這時值得每一個開發人員深思的問題。內存池(Memory Pool)就提供了一個比較可行的解決方案。

內存池在創建的過程中,會預先分配足夠大的內存,形成一個初步的內存池。然后每次用戶請求內存的時候,就會返回內存池中的一塊空閑的內存,並將這塊內存的標志置為已使用。當內存使用完畢釋放內存的時候,也不是真正地調用free或delete的過程,而是把內存放回內存池的過程,且放回的過程要把標志置為空閑。最后,應用程序結束,就會將內存池銷毀,將內存池中的每一塊內存釋放。

使用內存池的優點

1.減少內存碎片的產生。這個優點可以從創建內存池的過程中看出,當我們在創建內存池的時候,分配的都是一塊塊比較規整的內存塊,減少內存碎片的產生。

2.提高了內存的使用頻率。這個可以從分配內存和釋放內存的過程中看出。每次的分配和釋放並不是去調用系統提供的函數或操作符去操作實際的內存,而是在復用內存池中的內存。

使用內存池的缺點

缺點就是很可能會造成內存的浪費,因為要使用內存池需要在一開始分配一大塊閑置的內存,而這些內存不一定全部被用到。

數據庫連接池

數據庫連接池的基本思想是在系統初始化的時候將數據庫連接作為對象存儲在內存中,當用戶需要訪問數據庫的時候,並非建立一個新的連接,而是從連接池中取出一個已建立的空閑連接對象。在使用完畢后,用戶也不是將連接關閉,而是將連接放回到連接池中,以供下一個請求訪問使用。這些連接的建立、斷開都由連接池自身來管理。

同時,還可以設置連接池的參數來控制連接池中的初始連接數、連接的上下限數和每個連接的最大使用次數、最大空閑時間等。當然,也可以通過連接池自身的管理機制來監視連接的數量、使用情況等。

HttpClient連接池

HttpClient我們經常用來進行HTTP服務訪問。我們的項目中會有一個獲取任務執行狀態的功能使用HttpClient,一秒鍾請求一次,經常會出現Conection Reset異常。經過分析發現,問題是出在HttpClient的每次請求都會新建一個連接,當創建連接的頻率比關閉連接的頻率大的時候,就會導致系統中產生大量處於TIME_CLOSED狀態的連接。這個時候使用連接池復用連接就能解決這個問題。

總結

不難看出,這些池化技術的實現原理都是類似的,都是通過對連接或線程的復用,並對復用的數量、時間等進行控制,從而使系統的性能和資源消耗達到最優的狀態。

實際項目中,我們可以考慮使用池化技術來解決程序性能上的瓶頸。

 

"祝你歲月無波瀾,敬我余生不悲歡。"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM