使用COM处理Notes对象,内存泄漏
我使用C#与Domino COM进行交互。我正在使用LotusNotes8.5.2。VisualStudio2008,Windows7SP1 我正在尝试防止Lotus出现此错误:使用COM处理Notes对象,内存泄漏,com,memory-leaks,lotus-notes,lotus-domino,lotus,Com,Memory Leaks,Lotus Notes,Lotus Domino,Lotus,我使用C#与Domino COM进行交互。我正在使用LotusNotes8.5.2。VisualStudio2008,Windows7SP1 我正在尝试防止Lotus出现此错误: LSXBE: ************************************ LSXBE: ****** Out of Backend Memory ******* LSXBE: ************************************ 以下代码将NSF中的每个NotesDocument复制
LSXBE: ************************************
LSXBE: ****** Out of Backend Memory *******
LSXBE: ************************************
以下代码将NSF中的每个NotesDocument复制到另一个NSF。从具有SELECT@All选择查询的NotesView获取UNID后,代码使用
NotesDocument ndoc = nd.GetDocumentByUNID(nve.UniversalID);
ndoc.CopyToDatabase(nd2);
如果源NSF为10GB,我的应用程序使用的内存(我相信是私有字节)将稳定增长到450MB左右。ANTS Memory Profiler指出几乎所有的内存都分配给非托管内存,即COM
//建立会话
NotesSession ns=新的Domino.NotesSessionClass();
ns.初始化(“”);
//开源NSF
NotesDatabase nd=ns.GetDatabase(“,”test.nsf“,false);
//开放目的地NSF。
//假设nd2的所有设计元素与nd的相同
NotesDatabase nd2=ns.GetDatabase(“,“test2.nsf”,false);
//创建返回所有文档的视图。
NotesView nView 2=nd.GetView(“$All”);
创建视图(“所有DR”、“选择@All”、nView2、false);
NotesView nView=NotesConnectionDatabase.GetView(“所有DR”);
//循环浏览新视图中的条目
notesview-wentry-nvec=nView.AllEntries;
nve=nvec.GetFirstEntry();
对于(intj=1;j我不相信dominocom类本身会泄漏方法。但在这些类的后面是整个Notes运行时,它确实为缓存分配了大量内存,因此如果您看到内存增加也就不足为奇了。我不相信Domino COM类本身会泄漏。如果它们泄漏了,Lotus将提供一个循环()方法。但在这些类的后面是整个Notes运行时,它确实为缓存分配了大量内存,因此如果您看到内存增加,也就不足为奇了。您是否尝试过使用显式命令SetProcessWorkingSetSize()
传递参数-1和-1?有时.NET COM对象在显式调用之前不会释放内存。详细讨论了这一点
我遇到了类似的问题,这就解决了问题。您是否尝试过使用显式命令SetProcessWorkingSetSize()
传递参数-1和-1?有时.NET COM对象在显式调用之前不会释放内存。对此进行了更详细的讨论
我遇到了一个类似的问题,这就解决了问题。将此作为一个注释,因为我没有什么明确的说法。我不相信Domino COM类本身会泄漏。如果泄漏,Lotus将提供一个回收()方法。但在这些类的后面是整个Notes运行时,它确实为缓存分配了大量内存,因此,如果您看到内存增加,也就不足为奇了。我看不出有什么真正的问题。如果您的程序复制了10个jiggabytes并在没有OOM的情况下存活下来,那么发生泄漏的几率非常低。这是不可能的在GC.Collect()调用中,期望VM大小减小是一个非常常见的错误,这不是Windows中内存管理的工作方式。它会创建空堆块,它们会在下次分配时保留。这只是虚拟内存,不需要任何成本。在添加GC.Collect()之前在一台内存为4 GB的机器上,在每5000个文档之后,我都会收到一个错误,比如LSXBE:*******后端内存不足*********。我刚刚尝试过在每个文档之后使用GC.Collect。这将使内存利用率保持在75 MB左右,而不是450 MB。我希望这将给我在每个文档上执行额外操作的自由文档。我的应用程序速度降低了大约50%,这是可以接受的。@RichardSchwartz,如果你能将你的评论移到一个答案上,我想把它标记为一个答案。我相信你所说的COM类中缺少回收方法的说法是正确的。顺便说一句,我不确定你是否遇到过这个信息,所以我不知道hink我应该提一下……根据我的经验,Domino类工作得很好,但win64上存在一些已知的bug——特别是返回设计元素(视图、表单等)列表的方法。由于IBM从未正式证明win64支持这些类,因此如果您确实遇到任何bug,IBM修复它们的可能性很低。请将此作为评论,因为我没有任何明确的说法。我不相信Domino COM类本身会泄漏。如果真的发生漏洞,Lotus将提供一个循环e()方法。但在这些类的后面是整个Notes运行时,它确实为缓存分配了大量内存,因此,如果您看到内存增加,也就不足为奇了。我看不出有什么真正的问题。如果您的程序复制了10个jiggabytes并在没有OOM的情况下存活下来,那么发生泄漏的几率非常低。这是不可能的在GC.Collect()调用中,期望VM大小减小是一个非常常见的错误,这不是Windows中内存管理的工作方式。它会创建空堆块,它们会一直存在
//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.