私は 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) に割り当てられていることを示しています。
- 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 のリストを取得し、テキスト ファイルに書き込みます。b. コピーアプリを起動します。c. コピー アプリは、テキスト ファイルからレコードのサブセットをコピーします。d. コピー アプリが終了し、メモリが解放されます。e. マネージャー アプリは、新しいアプリ コピー プロセスを開始します。f. 必要に応じて c ~ e を繰り返します。