使用COM处理Notes对象,内存泄漏

使用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复制

我使用C#与Domino COM进行交互。我正在使用LotusNotes8.5.2。VisualStudio2008,Windows7SP1

我正在尝试防止Lotus出现此错误:

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

  • 我可以通过处理Notes对象来减少内存消耗吗?我还没有见过释放NotesSession、NotesDatabase、NotesDocument等的方法。有没有方法释放内存 我已经尝试过在每5000个文档之后调用GC.Collect()和GC.WaitForPendingFinalizers()的代码版本,这消除了在具有16GB RAM的机器上出现的“后端内存不足”错误。即使复制完成,并且我将包含以下代码的对象设置为null并调用垃圾收集,内存利用率仍然保持在450MB左右

    我还尝试将复制代码放在自己的线程中,然后在线程完成后进行垃圾收集。这没有帮助

  • 如果没有Notes对象的处理方法,我还可以如何降低内存利用率
  • 代码C#

    //建立会话
    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.