我有一个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执行其缓存更新和索引构建,这应该在此过程结束时完成。
答案 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)。请注意,它会禁用多个管道。