我使用C#与Domino COM进行交互。我正在使用Lotus Notes 8.5.2。 Visual Studio 2008,Windows 7 SP1。
我试图阻止Lotus的这个错误:
LSXBE: ************************************
LSXBE: ****** Out of Backend Memory *******
LSXBE: ************************************
以下代码将NSF中的每个NotesDocument复制到另一个NSF。从具有SELECT @All选择查询的NotesView获取UNID后,代码使用
一次复制一条消息NotesDocument ndoc = nd.GetDocumentByUNID(nve.UniversalID);
ndoc.CopyToDatabase(nd2);
鉴于,一个10 GB的源NSF,我的应用程序使用的内存量(我相信的私有字节)稳定增长到大约450 MB。 ANTS Memory Profiler表明几乎所有内存都分配给了非托管内存,即COM。
我在每5000个文档之后尝试了一个调用GC.Collect()和GC.WaitForPendingFinalizers()的代码版本,它消除了16 GB RAM机器上的“Out of Backend Memory”错误。即使复制完成,我将包含以下代码的对象设置为null并调用垃圾收集,内存利用率仍保持在450 MB左右。
我还尝试将复制代码放在自己的线程中,然后在线程完成后进行垃圾收集。这没有用。
代码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。我不知道那里是否存在问题。
这是一种非常笨拙的方式...... 构建一个新的经理应用程序 一个。获取列表UNID并将它们写入文本文件。 湾启动复制应用程序。 C。复制应用程序从文本文件中复制记录的子集。 d。复制应用程序终止,释放其内存。 即经理应用程序启动新的复制应用程序进程。 F。根据需要重复c - e。
答案 0 :(得分:1)
我不相信Domino COM类本身就会泄漏。如果他们这样做,Lotus将像他们在Java类中一样提供recycle()方法。但是在这些类的后面是整个Notes运行时,它确实为缓存分配了大量内存,所以如果你看到内存上升就不足为奇了。
答案 1 :(得分:0)
您是否尝试使用显式命令SetProcessWorkingSetSize()
传递参数-1和-1?有时.NET COM对象在显式调用之前不释放内存。 This article更详细地讨论了这一点。
我遇到了类似问题in this SO post,这解决了这个问题。