執行緒空間優化

2021-06-15 11:45:03 字數 1906 閱讀 5048

執行緒堆疊大小

c++記憶體分布

執行緒堆疊分布

首先,引出搜尋者方面問題是因為多執行緒程式設計中,一些執行緒沒有及時銷毀,導致儲存不足的情況,於是**一些解決方法。

1).執行緒分為核心態與使用者態。

首先是核心,指的是作業系統中最基礎的一些部分,提供一些分裝的結構,方法,對外部限制訪問許可權。即對於使用者是乙個只知道介面,不知道內部的結構。

核心態執行緒,即對核心可見執行緒,有比較小的資料堆疊,易於排程,排程依賴於作業系統,乙個執行緒阻塞,作業系統依據自己的策略排程其他可用執行緒,實現執行緒的併發。

使用者態執行緒,對於核心不可加,乙個執行緒阻塞時,如果使用者不手動排程,整個程序都會阻塞。

由於在專案中用createthread建立的執行緒已經是核心態的執行緒,故這裡沒有改進。

2).儲存變數分為五個區,堆,棧,自由區,全域性/靜態區,常量區

其中new 使用的是堆,全程序共享,查了一些資料,說堆最大為2gb。;malloc,區域性變數,函式呼叫時的引數傳遞會用到棧,如int *a=int[n]。

通常,每個執行緒乙個棧,每個程序乙個堆。所以執行緒數目的瓶頸在於執行緒自己的堆疊。這裡的堆疊僅僅指的是棧。visual c++編譯器預設設定是每個執行緒的堆疊

大小是1mb。

32位的計算機,位址記憶體空間為2^32,即4g,其中2g分配給使用者使用,給自己建立的執行緒分配的是虛擬記憶體。

一般當執行緒數為2000*1mb=2g時,會超過一般的限制,報錯。相應的64就最多8000個執行緒。

當然,如果在建立執行緒時指定較小的堆疊大小,就應該可以建立較多的執行緒。

檢視專案**中buffer的**段,如下:

m_p = new c* [size];

for (int i = 0; i < size; ++ i)

m_p[i] = null;

也就是說,這裡的緩衝區空間大部分用new 來建立,也就是放在程序共享的堆區,而不是執行緒的棧區,我們也就能夠通過修改每個執行緒的棧的大小來減少空間。

在vs2010下設定有兩個入口:

a.專案配置

b.createthread呼叫時的第二個引數;

執行時取其中較大的乙個。

於是,解決方法其中之一可以為修改執行緒棧大小。

3).然後又接觸到了乙個概念:執行緒池,查詢相關的部落格

這篇部落格比較詳細地介紹了執行緒池的概念,自己歸納總結如下:

諸如伺服器端,有時候要起許多處理短任務的執行緒,即執行緒實際執行的時間比執行緒建立和銷毀的時間長不了多少,這時候優化執行緒的建立銷毀就成了乙個問題。

於是引進執行緒池的概念,簡單地說就是建立兩個執行緒佇列,乙個空餘執行緒佇列,乙個忙碌執行緒佇列,來了任務,分配工作給空閒執行緒的第乙個執行緒,並把這個執行緒轉入到忙碌佇列中,這樣就實現了執行緒的共享機制。不過專案中執行的任務是檔案傳輸型的,一般來說執行緒處理的時間要遠遠大於執行緒建立和銷毀時間,所以如果引入執行緒池,應該沒有多大的改進效果,所以暫時不考慮執行緒池。

這裡對上述做乙個總結,本文**三個方法,核心態執行緒,減少執行緒棧大小,使用執行緒池,只有減少執行緒棧大小適用於我們專案的情況。

ps:補充一點,實際執行的時候,任務管理器顯示的記憶體占用不足100mb,執行緒並行有1300個是報錯。通過論壇上的討論得到如下資訊:

存用的雖然少,但預留的多,每個執行緒都要為執行緒預留棧空間,所以記憶體雖然沒用,但已經被執行緒「預訂」了。

vc生成的pe檔案預設每個執行緒保留棧大小是1m,所以1400個執行緒,就相當於「預訂」了1400m空間,而32位位址空間只有不到2g,所以提示沒有記憶體是合理的,因為確實沒有更多的記憶體做新建立的執行緒的棧了。

總結就是預定了虛擬空間,雖然沒顯示,但已經是不能用的。

11 儲存空間優化

redis 是乙個基於記憶體的資料庫,所有的資料都儲存在記憶體中 所以優化儲存 減少記憶體空間占用對成本控制來說非常重要。1.精簡鍵名和鍵值 2.內部編碼優化 redis 為每種資料型別提供了兩種內部編碼方式,並且 redis 會根據實際情況自動調整。共享物件 redis 啟動後會預先建立 1000...

Mysql優化碎片空間

mysql的表在使用的過程,會不斷產生碎片空間,占用儲存 1.查詢表的碎片空間 可以看到有120m左右的碎片空間 下面執行命令進行優化,表越大執行時間越長,執行過程中會鎖住表,切記在業務低峰操作 可以看到2g的資料,120m的碎片空整理用了8分鐘 此時再次檢視表空間使用情況 可以看到碎片空間被清理掉...

多執行緒優化

public void newexecute executorservice service executors.newfixedthreadpool threadnum 所有賬號總數 int accountcount accountdao.findallmerchantaccountcount i...