我使用 C# 与 Domino COM 交互。我正在使用 Lotus Notes 8.5.2。视觉工作室 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。
- 我可以通过处理 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。我不知道那里是否存在问题。
这是一种非常笨拙的方式......构建一个新的经理应用程序。获取列表 UNID 并将它们写入文本文件。湾。启动复制应用程序。C。复制应用程序从文本文件中复制一部分记录。d。复制应用程序终止,释放其内存。e. 管理器应用程序启动一个新的复制应用程序进程。F。根据需要重复 c - e。