c緩存池
1. 如何在C/C++程序中運用雙緩存雙線程等大規模數據處理的技巧 或者要怎麼做可以一次調入一塊數據進行處理
線程技術主要是用來並行處理一些任務,這些任務之間一般少有邏輯順序上的關聯,所以用線程技術可以提高程序整體的運行速度,特別在其中一些子線程運行速度有很大差距的情況下。
各類軟體使用緩存的方式都不一樣。雙緩存或者多個緩存、緩存池等等方式都有。關鍵在於你的程序需要使用怎樣的緩存結構。比如說你是類似生產者消費者模型的軟體,你也許會使用多個緩存做成隊列,一頭在不斷填充,一頭則不斷消耗,這樣能大大提高整體的數據吞吐速度。
fread不輸入整塊調入,它底層是使用的read之類的函數,對文件句柄進行操作。gets函數則是對指針指向的內存地址操作。這些都是上層邏輯了,離磁碟寄存器很遠。真正加快文件讀取速度的方法有很多,比如把整個文件映射到內存里,又比如跳過磁碟緩存直接大塊讀取內容。這些有的有專門的API函數可用,有的則需要你自己改寫系統底層代碼。
建議你多看看操作系統原理方面的書,可以去試著學習下linux內核代碼和原理,這樣你對這些問題就會有更深的認識。
希望這些建議能幫助你。
2. 怎樣解決sql Server內存不斷增加問題
為此,資料庫引擎獲取盡可能多的可用內存,同時保留足夠的可用內存以防操作系統交換內存。 SQL Server 實例在啟動時通常獲取8到12MB的內存以完成初始化過程。當實例完成初始化後,就不會再獲取更多的內存,直到用戶連接到該實例並開始產生工作負荷。這時,該實例根據需要不停地獲取內存以支持工作負荷。隨著更多的用戶連接並運行查詢,SQL Server 將獲取支持需求所需的額外內存。該實例將繼續獲取內存直到達到自身的內存分配目標,並且直到達到該目標的下限才會釋放任何內存。 為了在不產生多餘換頁 I/O 的情況下獲取盡可能多的內存,SQL Server 的每個實例都配置一個內存獲取目標,直到電腦的可用物理內存在4MB到10MB的范圍內。之所以選擇該范圍是因為測試表明 Windows NT 和 Windows 2000 都有最小內存交換,直到內存分配等於可用物理內存減去4MB。工作負荷處理任務重的 SQL Server 實例保留的可用物理內存為范圍的較低端 (4MB);工作負荷處理任務輕的實例保留的可用物理內存為范圍的較高端 (10MB)。 SQL Server 實例的目標隨工作負荷的改變而變化。當更多的用戶連接並產生更多的工作時,該實例傾向於獲取更多的內存以使可用的內存保持在4MB的限制以下。當工作負荷減輕時,該實例將其目標調整為 10MB的可用空間,並釋放內存給操作系統。將可用空間量保持在10MB和4MB之間可防止 Windows NT 或 Windows 2000 過多執行換頁操作,同時使 SQL Server 得以獲得盡可能最大的高速緩沖存儲器而不至引起額外的交換。 實例的目標內存配置和資料庫緩沖池的頁相對於可用池大小的需求有關。在任何實時點,緩沖區頁的總需求取決於滿足任何當前執行的查詢所需的數據頁數。假如相對於高速緩沖存儲器內的頁數,數據頁的需求很大,則當前在緩沖區內的每一頁很可能在相對較短的時間內由新頁替換。這可由緩沖區管理器對象的頁生命期性能計數器來度量。對於相對較小的緩沖區有較高需求的情況將生成短生命期,而純粹的影響就是使 I/O 增加,因為在頁可由多個邏輯讀取引用之前往往要被重寫。為減輕這個問題,資料庫引擎能夠獲取更多的內存以增加高速緩沖存儲器的大小。當頁生命期長時,資料庫引擎將可用內存定位於目標的高端 (10 MB);而當頁生命期短時,資料庫引擎定位於目標范圍的低端 (4MB)。 隨著其他應用程式在運行 SQL Server 實例的電腦上啟動,他們消耗內存致使可用物理內存量降到 SQL Server 的目標以下。SQL Server 實例於是從其地址空間釋放足夠內存,以使可用內存量回到 SQL Server 的目標。假如有其他應用程式停止運行而使可用內存增多,SQL Server 實例將增加其內存分配大小。SQL Server 能夠每秒釋放並獲取幾MB位元組的內存,這使他得以根據內存分配變化作出快速調整。 您能夠通過配置允許sql server能夠使用的最大內存來做限制: 最小和最大伺服器內存的影響 min server memory 和 max server memory 配置選項建立由 SQL Server 資料庫引擎使用的內存量的上限和下限。資料庫引擎並不立即獲取 min server memory 中指定的內存量。資料庫引擎啟動時只使用初始化所需的內存。隨著資料庫引擎工作負荷的增加,他將繼續獲取支持工作負荷所需的內存。資料庫引擎直到到達 min server memory 中指定的內存量才會釋放任何所需的內存。一旦到達 min server memory,資料庫引擎將使用標准演算法(使操作系統的可用內存保持在 4MB到 10MB之間)獲取和釋放所需內存。唯一的區別是資料庫引擎從不將內存分配降到 min server memory 所指定的水平下,也從不獲取超過max server memory 所指定水平的內存。 資料庫引擎獲取的內存量完全取決於放置在實例上的工作負荷。不處理很多請求的 SQL Server 實例可能永遠達不到 min server memory。 假如為 min server memory 和 max server memory 指定相同的值,則一旦分配給資料庫引擎的內存達到該值,資料庫引擎將停止動態釋放和獲取內存。 假如在運行 SQL Server 實例的電腦上頻繁啟動或停止其他應用程式,啟動這些應用程式所需的時間可能會因 SQL Server 實例分配和釋放內存而延長。另外,假如 SQL Server 是幾個在一台電腦上運行的伺服器應用程式中的一個,系統管理員可能需要控制分配給 SQL Server 的內存量。
3. 為什麼說python採用的是基於值的內存管理模式
先從較淺的層面來說,Python的內存管理機制可以從三個方面來講
(1)垃圾回收
(2)引用計數
(3)內存池機制
一、垃圾回收:
python不像C++,Java等語言一樣,他們可以不用事先聲明變數類型而直接對變數進行賦值。對Python語言來講,對象的類型和內存都是
在運行時確定的。這也是為什麼我們稱Python語言為動態類型的原因(這里我們把動態類型可以簡單的歸結為對變數內存地址的分配是在運行時自動判斷變數
類型並對變數進行賦值)。
二、引用計數:
Python採用了類似Windows內核對象一樣的方式來對內存進行管理。每一個對象,都維護這一個對指向該對對象的引用的計數。如圖所示(圖片來自Python核心編程)
x = 3.14
y = x
我們首先創建了一個對象3.14, 然後將這個浮點數對象的引用賦值給x,因為x是第一個引用,因此,這個浮點數對象的引用計數為1. 語句y =
x創建了一個指向同一個對象的引用別名y,我們發現,並沒有為Y創建一個新的對象,而是將Y也指向了x指向的浮點數對象,使其引用計數為2.
我們可以很容易就證明上述的觀點:
變數a 和 變數b的id一致(我們可以將id值想像為C中變數的指針).
我們援引另一個網址的圖片來說明問題:對於C語言來講,我們創建一個變數A時就會為為該變數申請一個內存空間,並將變數值
放入該空間中,當將該變數賦給另一變數B時會為B申請一個新的內存空間,並將變數值放入到B的內存空間中,這也是為什麼A和B的指針不一致的原因。如圖:
而Python的情況卻不一樣,實際上,Python的處理方式和Javascript有點類似,如圖所示,變數更像是附在對象上的標簽(和引用的
定義類似)。當變數被綁定在一個對象上的時候,該變數的引用計數就是1,(還有另外一些情況也會導致變數引用計數的增加),系統會自動維護這些標簽,並定
時掃描,當某標簽的引用計數變為0的時候,該對就會被回收。
三、內存池機制
Python的內存機制以金字塔行,-1,-2層主要有操作系統進行操作,
第0層是C中的malloc,free等內存分配和釋放函數進行操作;
第1層和第2層是內存池,有Python的介面函數PyMem_Malloc函數實現,當對象小於256K時有該層直接分配內存;
第3層是最上層,也就是我們對Python對象的直接操作;
在 C 中如果頻繁的調用 malloc 與 free 時,是會產生性能問題的.再加上頻繁的分配與釋放小塊的內存會產生內存碎片. Python 在這里主要乾的工作有:
如果請求分配的內存在1~256位元組之間就使用自己的內存管理系統,否則直接使用 malloc.
這里還是會調用 malloc 分配內存,但每次會分配一塊大小為256k的大塊內存.
經由內存池登記的內存到最後還是會回收到內存池,並不會調用 C 的 free
釋放掉.以便下次使用.對於簡單的Python對象,例如數值、字元串,元組(tuple不允許被更改)採用的是復制的方式(深拷貝?),也就是說當將另
一個變數B賦值給變數A時,雖然A和B的內存空間仍然相同,但當A的值發生變化時,會重新給A分配空間,A和B的地址變得不再相同;
而對於像字典(dict),列表(List)等,改變一個就會引起另一個的改變,也稱之為淺拷貝:
附錄:
引用計數增加
1.對象被創建:x=4
2.另外的別人被創建:y=x
3.被作為參數傳遞給函數:foo(x)
4.作為容器對象的一個元素:a=[1,x,』33』]
引用計數減少
1.一個本地引用離開了它的作用域。比如上面的foo(x)函數結束時,x指向的對象引用減1。
2.對象的別名被顯式的銷毀:del x ;或者del y
3.對象的一個別名被賦值給其他對象:x=789
4.對象從一個窗口對象中移除:myList.remove(x)
5.窗口對象本身被銷毀:del myList,或者窗口對象本身離開了作用域。
垃圾回收
1、當內存中有不再使用的部分時,垃圾收集器就會把他們清理掉。它會去檢查那些引用計數為0的對象,然後清除其在內存的空間。當然除了引用計數為0的會被清除,還有一種情況也會被垃圾收集器清掉:當兩個對象相互引用時,他們本身其他的引用已經為0了。
2、垃圾回收機制還有一個循環垃圾回收器, 確保釋放循環引用對象(a引用b, b引用a, 導致其引用計數永遠不為0)。