6

我有一个 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();
    }
}

当此循环运行并在任务管理器中查看时,进程内存使用量随着时间的推移而增加。

SitecoreItem类没有实现IDisposable接口,所以我不能调用创建项的终结器。

如何避免这种内存泄漏?

PS:我正在使用 Windows 应用程序来执行此操作以绕过 IIS 进程内存泄漏,Sitecore 在此进行缓存更新和索引构建,这应该在此过程结束时完成。

4

3 回答 3

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,它会在某个时候自动发生,您只是不知道何时。

于 2013-05-17T07:33:26.583 回答
0

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

如果这种情况,简单地设置一个较低的缓存限制将意味着缓存在需要时被清空,这似乎是一种更健康的方式来控制事情。

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

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

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

(另见这个答案)。请注意,它会禁用多个管道。

于 2013-05-28T13:58:16.350 回答
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();
}

感谢所有的支持者!

于 2013-05-17T12:29:38.927 回答