1

私は 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 を取得した後、コードは一度に 1 つのメッセージをコピーします。

NotesDocument ndoc = nd.GetDocumentByUNID(nve.UniversalID);         
ndoc.CopyToDatabase(nd2);

ソース NSF が 10 GB の場合、アプリケーションが使用するメモリの量 (プライベート バイトだと思います) は、約 450 MB まで着実に増加します。ANTS Memory Profiler は、そのメモリのほとんどすべてがアンマネージ メモリ (COM) に割り当てられていることを示しています。

  1. Notes オブジェクトを破棄することでメモリ消費を削減できますか? NotesSession、NotesDatabase、NotesDocument などの割り当てを解除するメソッドを見たことがありません。メモリの割り当てを解除する方法はありますか?

5000 ドキュメントごとに GC.Collect() および GC.WaitForPendingFinalizers() を呼び出すコードのバージョンを試しました。これにより、16 GB RAM を搭載したマシンで「バックエンド メモリ不足」エラーが解消されました。コピーが終了し、以下のコードを含むオブジェクトを null に設定してガベージ コレクションを呼び出しても、メモリ使用率は約 450 MB のままです。

また、コピー コードを独自のスレッドに入れて、スレッドの完了後にガベージ コレクションを実行してみました。それは助けにはなりませんでした。

  1. 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.

私はこれらのアイデアを持っていますが、どれも魅力的ではありません:

  1. CopyToDatabase を呼び出すたびにガベージ コレクションを呼び出します。COM のメモリ リークに対処していると思われるので、これが機能するとは思わない。また、アプリケーションの速度が低下することも期待しています。

  2. C++ API を試してください。そこに問題が存在するかどうかはわかりません。

  3. これは非常に不器用な方法です... 新しい管理アプリを作成します。UNID のリストを取得し、テキスト ファイルに書き込みます。b. コピーアプリを起動します。c. コピー アプリは、テキスト ファイルからレコードのサブセットをコピーします。d. コピー アプリが終了し、メモリが解放されます。e. マネージャー アプリは、新しいアプリ コピー プロセスを開始します。f. 必要に応じて c ~ e を繰り返します。

4

2 に答える 2

1

DominoCOMクラス自体がリークするとは思わない。もしそうなら、LotusはJavaクラスで行うのと同じ方法でrecycle()メソッドを提供します。ただし、これらのクラスの背後には、Notesランタイム全体があり、キャッシュに大量のメモリが割り当てられるため、メモリが増えても驚くことではありません。

于 2013-02-16T00:14:45.687 に答える