6

私は、別のシステムのループ内に多数のSitecoreアイテムを作成する必要があるSitecoreアプリケーションを使用しています。以下は私のテスト目的のループです。大量のSitecoreアイテムを作成するとメモリリークが発生する

using (new Sitecore.SecurityModel.SecurityDisabler()) 
{ 
    for (int i = 0; i < 20000; i++) 
    { 
     Item newItem = MyTemplateItem.CreateItemFrom(DateTime.Now.Ticks.ToString(), myParentItem); 

     newItem.Editing.BeginEdit(); 
     newItem.Fields["Title"].Value = Guid.NewGuid().ToString(); 
     newItem.Editing.EndEdit(); 
    } 
} 

このループが実行中で、タスクマネージャーを見ているときに、プロセスメモリの使用量が増えています。

Sitecore ItemクラスはIDisposableインターフェイスを実装していないため、作成したアイテムのファイナライザを呼び出すことができません。

このメモリリークを回避するにはどうすればよいですか?

PS:この処理を実行するためにWindowsアプリケーションを使用していますが、このプロセスの最後にSitecoreがキャッシュの更新とインデックスの作成を行うIISプロセスのメモリリークを回避します。

+0

本当にリークですか?あなたは、メモリを割り当てる必要があり、ループでそれを行う関数を実行しています。プロセスメモリが上がったからといって、それがリークであるとは限りません。記憶は決して落ちませんか? – ddysart

+0

私の用語は正しいと思います。メモリは増え続けていて、RAMがいっぱいになるとPCが再起動します。そのメモリリーク。私はループを約1時間監視しました。 –

答えて

3

あなたは一時的にアイテムの作成時にデータベース・キャッシュを無効にすることができます

using (new Sitecore.Data.DatabaseCacheDisabler()) 

あなたが使用して作成中のインデックスを無効にすることができます

Sitecore.Configuration.Settings.Indexing.Enabled = false; 

これら二つのことを追加し、それが助けかどうかを確認してください。

更新日: これはうまくいくかもしれません。 EndEdit()の後に、あなたのループ内にこれを追加します。

newItem = null; 

if (i % 100 == 0) 
{ 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
} 

それは未使用のメモリ100個の項目が追加されているすべての時間を取り戻すしようとするガベージコレクタを強制します。

これは、実際にGCを自分で呼び出す必要はありません、それは自動的にある時点で発生します、あなたは時を知らない。

+0

返事をありがとう。私はあなたの提案を試みましたが、私は記憶の成長に何の変化もありません。 –

+0

私の答えに別の提案を追加しました –

+0

GC.Collectは非常にCPU集約的なプロセスなので、一般的にはAppPool全体をブロックするので、その呼び出しは避けてください。 – ddysart

0

ルードの答えはそれよりもうまくいくようです。メモリの増加は、データベースのキャッシュ構築のために急速でした。ディセーブルにするとメモリの成長が大幅に遅くなりますが、それでも成長は非常に遅いです。

私はそれを達成するために次のステートメントを使用しました。

using (new Sitecore.Data.DatabaseCacheDisabler()) 

newItem = null; // did not worked 

// replaced above line with the below 
Marshal.Release(Marshal.GetIUnknownForObject(newItem)); 

if (i % 100 == 0) 
{ 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
} 

すべての支持者に感謝します!

0

キャッシュの上限を高すぎる(つまり高すぎる)ように設定していて、何をやっているのかは、報告している症状を得るのが妥当と思われます。この場合、スクリプトが実行されている間に/sitecore/admin/cache.aspxページが表示されます。私は維持するための健康的な方法と思われ、この場合であれば、単に下キャッシュ制限を設定することは、必要に応じてキャッシュが空であることを意味します

...エントリmaster[items]master[data]が登山に維持する画像をいただきたいですコントロール下のもの。

あなたは劇的に

using (new BulkUpdateContext()) { code.. }

を使用してみてください、おそらく、プログラムによるアイテムの作成をスピードアップしたい場合にも、それはBulkUpdateContextは()もキャッシュに項目を追加スキップしている可能性があります - この場合、私はチェックしていませんそのような場合は、あなたが持っている記憶の問題を「修正」する可能性もあります。

this SO answerも参照)。いくつかのパイプラインを無効にすることに注意してください。

関連する問題