深解WOSA XFS中的記憶體分配函式

2021-07-24 05:35:13 字數 2386 閱讀 1815

微軟制定wosa/xfs規範,並不是一件簡單的事情。如果對windows作業系統本身理解的足夠深入的話,會理解wosa架構裡面的很多內容,遠不是想象的那麼簡單。首先我們要清楚wosa架構並不是只存在於xfs規範中,微軟還有很多地方在使用wosa架構,比較常見的如winsock套接字、odbc資料庫等。所有的這些都用到同樣的軟體架構,差別的只是具體的擴充套件有些許不同而已。

對於上面的四個函式來講,wfmfreebuffer和wfsfreeresult可以合為乙個來看,因為wfsfreeresult主要是提供給上層應用程式釋放sp返回的wfsresult結構的,其內部實現與wfmfreebuffer一樣,所以我們可以認為wosa/xfs中只有三個記憶體管理函式wfmallocatebuffer、wfmallocatemore、wfmfreebuffer。這三個函式與c語言裡面的庫函式malloc、realloc、free的功能是一一對應的。wfmallocatebuffer用來分配一塊記憶體,wfmallocatemore是在wfmallocatebuffer分配的基礎上再多分配一塊記憶體,wfmfreebuffer是用來釋放前兩者分配的記憶體的。

既然是這樣,我們顯而易見的乙個問題是為什麼wosa/xfs架構中另外提供三個函式來管理記憶體,而不是直接使用c語言的庫函式呢?

(以下為了便於理解,稱xfs manager層上面叫做atmc應用,xfs manager層下面的叫做sp,請做好區分)

考慮一下wosa/xfs規範提到什麼情況下應該用這幾個記憶體管理函式?是atmc應用需要將記憶體資料通過xfs manager傳到sp裡面,或者相反,sp需要將記憶體資料通過xfs manager傳到atmc應用裡面,也就是只有在atmc應用和sp之間需要傳送資料時才用wosa/xfs提供的記憶體管理函式。比如最常見的情況,atmc應用呼叫wf***ecute命令時傳入的引數 lpvoid lpcmddata,它是要用wfmallocatebuffer來分配的,最後在sp裡面呼叫wfmfreebuffer來釋放。

如果你認為atmc在呼叫wf***ecute可以直接使用malloc或者new來分配記憶體,代替wfmallocatebuffer,這種看法是錯誤的。可能根據你的經驗,發現直接用malloc或者new,整個atmc應用也可以正常執行,但不表示它可以在其他廠家的sp上面執行。因為呼叫wf***ecute的地方,你可能是用vc編譯器來寫的atmc應用,而呼叫的sp恰恰也是用vc寫的,那麼你們的malloc或者new的分配策略是一樣的,沒有問題。但是很多時候並不是都用vc來編寫的atmc應用和sp,可能你用vc編寫atmc應用,但是廠家的sp是用c++ builder來編譯,或者用不出名的c/c++編譯器來編譯,每個編譯器對於c/c++規範中的malloc或者new實現不同,不能保證malloc或者new的通用性(一般是通用的)。更進一步考慮,如果廠家用非c/c++的語言來寫sp,那它的sp根本不會理解atmc傳下了的記憶體。

同樣,atmc應用也可以用不同的語言來呼叫api,甚至整個atm軟體中用多種程式語言寫各個模組,它們之間的互動也就更加複雜。

正因為存在上面提到的問題,wosa/xfs需要統一記憶體的分配管理,只要通過xfs manager互動資料,就需要使用其提供的記憶體管理函式,這樣就會保證atmc應用和sp之間對記憶體解釋的是完全一致的。一樣的情況在軟體行業並不鮮見,如果熟悉微軟的com技術,就會知道為了統一com領域的記憶體分配策略,微軟提供了cotaskmemalloc系列函式來避免com元件之間對記憶體分配的差異。

現在我們應該明白了在wosa/xfs中要盡量使用其提供的記憶體管理函式,而不要使用其他的記憶體分配函式。但是如果你的記憶體位址不通過xfs manager層來傳送,比如在你的sp內部,是可以用malloc、new來分配記憶體的。因為是在sp內部使用這些記憶體,你的sp都是用同乙個編譯器來編譯,所以不存在對記憶體分配解釋差異的問題;但是,如果你的sp各個模組都會用不同的編譯器來寫,那也要使用wosa/xfs提供的函式為好。

總之,只要兩個模組可能存在用不同語言或者編譯器的情況,就要考慮使用wosa/xfs提供的記憶體管理函式。

wosa/xfs提供的記憶體管理函式還有個很好的功能,就是它的wfmfreebuffer是可以釋放記憶體鏈的。如果對wfmallocatebuffer、wfmallocatemore比較熟悉,就會知道當用wfmallocatemore分配時,其與最開始分配的記憶體頭是連線在一起的,形成乙個鍊錶結構。釋放時不需要將鍊錶中每個節點都釋放,只需呼叫wfmfreebuffer將煉表頭釋放,則該鍊錶中所有的節點都會被釋放了。wosa/xfs裡面有很多結構,有了這個特性,那就太好了,我們省了很多事。但是要小心使用這個特性,如果用不好鏈式分配的功能,很容易導致atm軟體崩潰,尤其是使用象kal平台的測試工具時,很容易就看到網頁異常了。

wosa/xfs提供的記憶體管理函式存在乙個問題就是它是基於記憶體對映檔案的,分配的效率和速度比malloc等差了很多,不過對於atm軟體來說,這些效率的降低也不需要多加在意,畢竟不是作業系統核心處理程式,況且用記憶體對映機制還有利於記憶體共享,至於wosa/xfs中利用記憶體對映機制進行跨程序記憶體共享在這裡就不多說了。

ObjectC oc中的記憶體分配

一 記憶體分配順序 程式一啟動的時候就會先載入 區中的 然後載入常量區中的常量,接著載入全域性區和靜態區 初始化過的靜態區和沒有初始化過的靜態區是分開的 以上四個區都是隨著程式啟動而載入到記憶體中,隨著程式的退出而銷毀。程式設計師不需要管理這一塊的記憶體。堆區 堆區用來存放物件,需要使用alloc來...

IOS中記憶體的分配

記憶體分割槽 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os ios中alloc都是存放在堆中 3 全域性區 靜態區 static 全域性變數和靜態...

C 中的記憶體分配

在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區堆 堆就是那些由 new 分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般乙個 new 就 要對應乙個 delete。如果程式設計師沒有釋放掉,那麼在程式結束後,作業系統會自動 堆可以動態地擴...