我使用C#與Domino COM進行交互。我正在使用Lotus Notes 8.5.2。 Visual Studio 2008,Windows 7 SP1。處理Notes對象與COM,內存泄漏
我試圖防止這種錯誤從Lotus:
LSXBE: ************************************
LSXBE: ****** Out of Backend Memory *******
LSXBE: ************************************
下面的代碼將每個NotesDocumentCollection中的NSF到另一個NSF。使用
NotesDocument ndoc = nd.GetDocumentByUNID(nve.UniversalID);
ndoc.CopyToDatabase(nd2);
鑑於,10 GB,內存量(專用字節,相信)的源具有NSF在時間SELECT @All的選擇查詢,代碼拷貝一個消息從一個爲NotesView得到UNIDs後由我的應用程序使用穩步增長到約450 MB。 ANTS Memory Profiler表明幾乎所有的內存都分配給非託管內存,這將是COM。
- 可以通過處理Notes對象來減少內存消耗嗎?我還沒有看到解除分配NotesSession,NotesDatabase,NotesDocument等方法。有沒有辦法解除分配內存?
我都想盡5000個文檔後一個版本()的代碼中調用所以GC.Collect和GC.WaitForPendingFinalizers()的,與16 GB RAM淘汰了機上的「走出後端內存不足」的錯誤。即使在複製完成時,我將包含以下代碼的對象設置爲null並調用垃圾回收,內存利用率仍保持在450 MB左右。
我也嘗試將複製代碼放在它自己的線程中,然後在線程完成後進行垃圾收集。這沒有幫助。
- 如果沒有Notes對象的處理方法,我該如何減少內存使用率?
代碼C#
//Establish session
NotesSession ns = new Domino.NotesSessionClass();
ns.Initialize("");
//Open source NSF
NotesDatabase nd = ns.GetDatabase("", "test.nsf", false);
//Open destination NSF.
//Assume that all design elements of nd2 are identical to those of nd
NotesDatabase nd2 = ns.GetDatabase("", "test2.nsf", false);
//Create view that returns all documents.
NotesView nView2 = nd.GetView("$All");
nd.CreateView("All-DR", "SELECT @ALL", nView2, false);
NotesView nView = NotesConnectionDatabase.GetView("All-DR");
//Loop through entries in the new view
NotesViewEntry nvec = nView.AllEntries;
nve = nvec.GetFirstEntry();
for (int j = 1; j <= intEntryCount; j++)
{
if (j == 1)
{
nve = nvec.GetFirstEntry();
}
else
{
nve = nvec.GetNextEntry(nve);
}
//Copy document to second database.
NotesDocument ndoc = nd.GetDocumentByUNID(nve.UniversalID);
ndoc.CopyToDatabase(nd2);
}
//End loop.
//All documents are copied.
我有這些想法,其中沒有一個是吸引人:
呼叫垃圾收集每次調用CopyToDatabase後。我不認爲這會工作,因爲我相信我正在處理COM中的內存泄漏。我也希望它能夠降低我的應用程序的速度。
嘗試使用C++ API。我不知道這個問題是否存在。
這是一個非常笨拙的方式... 建立一個新的經理應用程序, a。獲取UNID列表並將它們寫入文本文件。 b。開始複製應用程序。 c。複製應用程序從文本文件複製記錄的一個子集。 d。複製應用程序終止,釋放其內存。 e。經理應用程序啓動新的複製應用程序進程。 f。根據需要重複c-e。
把它作爲評論,因爲我沒有任何明確的說法。本人並不相信Domino COM類泄漏。如果他們這樣做了,Lotus會按照他們在Java類中的方式提供recycle()方法。但是在這些類的後面是整個Notes運行時,它會爲緩存分配大量內存,所以如果看到內存在增加,這並不奇怪。 – 2013-02-15 01:03:27
我沒有看到這裏真正的問題的證據。如果你的程序拷貝了10個jigabytes並且沒有OOM而存活,那麼泄漏的機率很低。在GC.Collect()調用期間減少虛擬機大小是一個非常常見的錯誤,這與內存管理在Windows中的工作方式不同。它創建空的堆塊,他們留待下一次分配。這只是虛擬內存,它不需要任何成本。 – 2013-02-15 17:36:30
在每個第5000個文檔之後添加GC.Collect()之前,在具有4 GB RAM的機器上,我確實收到類似 的錯誤LSXBE:****** Out of Backend Memory *******。 我剛剛在每個單獨的文檔之後嘗試過GC.Collect。這使內存利用率保持在75 MB左右,而不是450 MB。我希望這會讓我自由地對每個文檔執行額外的操作。我的申請速度減少了大約50%,這是可以接受的。 – 2013-02-15 22:50:01