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

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

当此循环正在运行并且在任务管理器中查看时,进程内存使用量随着时间的推移而增加。
Sitecore Item类没有实现IDisposable接口,因此我无法调用所创建项目的终结器。
如何避免此内存泄漏?
PS:我正在使用Windows应用程序执行此操作,以绕过IIS进程内存泄漏,其中Sitecore执行其缓存更新和索引构建,这些应在此过程的结尾完成。

1
你确定这真的是一个泄漏吗?你正在执行必须分配内存的函数,并在循环中执行。仅因为处理器内存增加并不意味着存在泄漏。内存永远不会下降吗? - Derek Dysart
1
我认为我的术语是正确的,内存不断增长,如果RAM已满,则会重启PC。这是一个内存泄漏。我已经监视了循环约一个小时。 - Sandun Perera
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,它会在某个时刻自动发生,只是你不知道什么时候。


谢谢您的回复。我尝试了您的建议,但内存增长没有任何改变。 - Sandun Perera
在我的答案中又添加了一个建议。 - Ruud van Falier
一般情况下,应避免调用GC.Collect,因为它是一个非常消耗CPU的过程,在执行期间会阻塞整个AppPool。 - Derek Dysart

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

感谢所有的支持者!


0

如果您将缓存限制设置得太高并执行您正在执行的操作,那么出现您报告的症状似乎是合理的。在运行脚本时查看页面/sitecore/admin/cache.aspx 将显示是否为此情况。我想象中的条目master[items]master[data]将继续增加...

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

此外,如果您想大幅加快编程式项目创建的速度,可以尝试使用

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接