新聞中心
前段時間寫了一篇日志叫《讓C++更像C#》,但我寫的那段示例代碼中的有關(guān)內(nèi)存泄漏的問題當(dāng)時我說先不管,其實是那時沒有找到很好的解決方法。不好解決C#內(nèi)存泄露的原因是,沒有辦法去判斷一個指針到底是指向堆內(nèi)存,還是指向棧內(nèi)存(windows系統(tǒng)沒有API來實現(xiàn)這樣的功能)。當(dāng)時google、baidu都搜遍了,沒有找到解決辦法。

現(xiàn)在,就進(jìn)一步研究這個C#內(nèi)存泄露的問題。
今天在看國外的一篇技術(shù)文章的時候,發(fā)現(xiàn)有人就在研究這個問題!他給出了一種解決辦法。首先把他介紹,操作系統(tǒng)會為每一個系統(tǒng)中運行的線程分配一個數(shù)據(jù)結(jié)構(gòu)叫做TIB(Thread Information Block)或者叫TEB(Thread Enviroment BLock)。里面記錄了與某個線程相關(guān)的所有信息。當(dāng)然包括線程相關(guān)的堆棧地址信息。而堆棧的棧頂與?;贩謩e存放在FS寄存器的4與8位置處。所以他通過嵌入式匯編實現(xiàn)了判斷指針是棧指針,還是堆指針的方法。代碼如下:
- bool IsMemoryOnStack( LPVOID pVoid )
- {
- LPVOID dwStackTop = 0;
- LPVOID dwStackLowCurrent = 0;
- __asm
- {
- mov EAX, FS:[4]
- mov dwStackTop, eax
- mov EAX, FS:[8]
- mov dwStackLowCurrent, eax
- }
- if( pVoid < = dwStackTop && pVoid >= dwStackLowCurrent )
- {
- // The memory lie between the stack top and stack commited.
- return true;
- }
- // Pointer dosen't point to the stack
- return false;
- }
現(xiàn)在只需要把CTest可能引起內(nèi)存泄漏的函數(shù)修改為如下,就可以解決問題了:
- CTest(CTest* & t)
- {
- this->x=t->getX();
- if(!IsMemoryOnStack(t))
- {
- delete t;
- t=0;
- }
- }
這里使用指針引用的好處是在防止在釋放了指針的內(nèi)存后,用戶繼續(xù)訪問指針的內(nèi)存。
到此為止,問題全部解決了!印度的軟件行業(yè)確實是挺牛比的!
這樣,這個C#內(nèi)存泄露問題就解決了。有關(guān)TIB的技術(shù)參考為:
http://www.microsoft.com/msj/archive/S2CE.aspx
新聞名稱:再談讓C++更像C#:C#內(nèi)存泄露問題
鏈接地址:http://www.dlmjj.cn/article/djdgiii.html


咨詢
建站咨詢
