2012-09-19 91 views
3

我的MEX file是用C++/CLI編寫的,並且調用了用C#編寫的DLL。MATLAB中的內存泄漏> MEX文件>管理的DLL

當gcnew'ing一個對象,不應該在mexFunction返回時被垃圾收集? 它的引用應該丟失,但似乎沒有垃圾收集...每個調用mex函數增加MATLAB的內存分配(並且不,內存不用於MATLAB變量)。

我已經嘗試創建一個範圍較窄的大型虛擬值,並且在單步執行MEX文件時,我可以看到分配和釋放的內存。但不是在mexFunction中創建的主要對象=(

我試圖在析構函數和終結器中刪除它,但我無法將它收集到垃圾回收。如何在返回時釋放託管內存?以MATLAB

我不認爲外部DLL文件管理器是問題爲了說明,我創造了這個傻mexFunction:

public ref class Foo 
{ 
    public: 
     Foo() 
     { 
      Dictionary<int,String^>^ bar = gcnew Dictionary<int,String^>; 
      for(int i=0;i<10000000;i++) 
      { 
       bar->Add(i, "abcdefghijklmnopqrstuvxyz"); 
      } 
     } 
}; 

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, mxArray* prhs[]) 
{ 
    Foo^ test = gcnew Foo(); 
} 

這大約300名  MB顛簸MATLAB的記憶,雖然後續調用別t進一步增加內存,就像在我的真實MEX文件中一樣。

編輯:

我回答我自己的問題,罪魁禍首是mxArrayToString

+0

聽起來像mexFunction問題,你是否使用'mex'函數分配和解除分配內存?只是一個想法,你確定該DLL沒有泄漏? – macduff

回答

2

我發現了問題,原來它畢竟......爲紅鯡魚

抱歉,因爲我沒有使用新的malloc或mxMalloc我錯誤地認爲我所有的非託管不是.NET相關內存將在堆棧中並在mexFunction結束時清除。

但是,mxArrayToString不會像mxGetData和其他mx *函數那樣返回指向MATLAB數據的指針。它將數據複製到堆中,並且必須調用mxFree來釋放它。我使用mxArrayToString作爲輸入來創建一個System :: String ^,唯一需要的改變是保存一個臨時字符指針,將其用於String ^構造函數,然後使用mxFree。

所以再次對SEO:從mxArrayToString指針必須mxFree'd

2

垃圾收集標記爲可用的.NET堆內存裏面。它不會縮小.NET堆(這會使內存可用於其他進程,並且可以爲進程中的非.NET代碼提供地址空間)。

明確記錄了大對象堆永遠不會收縮,並且具有一千萬條目的字典可能足夠大以進入LOH。

+0

我看到...我正在閱讀的數據非常大,所以它在LOH中是有意義的,但是我最初的問題是每次調用的內存不斷增加,最終耗盡所有系統內存。我知道如果內存不釋放,但不應該至少被重用? (因爲它似乎在我的微不足道的情況下......?)引用是否能夠存活,留下mexFunction來保存GC的內存? – Simon

+0

好吧,LOH也沒有壓縮,所以它受到碎片化。這可以解釋爲什麼最終分配新內存而不是重新使用舊內存。 –