创建大量Sitecore项会导致内存泄漏

时间:2013-05-17 05:29:31

标签: .net memory-management memory-leaks garbage-collection 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应用程序来执行此操作以绕过IIS进程内存泄漏,其中Sitecore执行其缓存更新和索引构建,这应该在此过程结束时完成。

3 个答案:

答案 0 :(得分: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,它会在某个时刻自动发生,你只是不知道什么时候。

答案 1 :(得分:0)

Ruud的回答似乎比以前更好。由于数据库缓存的建立,内存的增长很快。通过禁用大幅减缓内存增长,但增长仍然非常缓慢。

我使用以下语句来实现它;

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();
}

感谢所有支持者!

答案 2 :(得分:0)

如果您将缓存限制设置为高值(即太高)并执行您正在执行的操作,那么获取您报告的症状似乎是合理的。在脚本运行时查看页面/sitecore/admin/cache.aspx将显示是否是这种情况。我会对条目master[items]进行图像处理,而master[data]会继续攀登......

如果 这种情况,只需设置较低的缓存限制即可意味着根据需要清空缓存,这似乎是一种更加健康的方式来控制事物。

此外,如果您想大大加快程序化项目的创建速度,也许可以尝试使用

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

BulkUpdateContext()也可能会跳过向缓存添加项目 - 我没有检查是否是这种情况,但如果是这样,它也可能“修复”你的内存问题。

(另见this SO answer)。请注意,它会禁用多个管道。