Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 创建大量Sitecore项目会导致内存泄漏_.net_Memory Management_Memory Leaks_Garbage Collection_Sitecore - Fatal编程技术网

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

.net 创建大量Sitecore项目会导致内存泄漏,.net,memory-management,memory-leaks,garbage-collection,sitecore,.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(), myParentIt

我有一个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.SecurityModel.SecurityDisabler())
{
对于(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将在该进程结束时进行缓存更新和索引生成。

您可以在项目创建过程中临时禁用数据库缓存:

using (new Sitecore.Data.DatabaseCacheDisabler())
您可以使用以下方法在创建过程中禁用索引:

Sitecore.Configuration.Settings.Indexing.Enabled = false;
试着把这两件事加起来,看看是否有帮助

更新: 也许这会奏效。 在EndEdit()之后的循环中添加此项:

它将强制垃圾收集器在每次添加100个项目时尝试回收未使用的内存


如果这样做有效,那么你就不必亲自调用GC,它会在某个时候自动发生,你只是不知道什么时候发生。

鲁德的答案似乎比以前更有效。由于数据库缓存的构建,内存的增长很快。通过禁用会大大降低内存的增长速度,但内存的增长仍然非常缓慢

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

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

谢谢所有的支持者

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

如果是这样的话,只需设置一个较低的缓存限制,就意味着缓存会根据需要清空,这似乎是一种更健康的控制方式

另外,如果您想显著加快编程项的创建,可以尝试使用

使用(新BulkUpdateContext())
{
代码。。
}

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


(另见附件)。请注意,它禁用了几个管道。

谢谢您的回复。我尝试了你的建议,但我没有改变内存增长。在我的回答中添加了另一个建议一般来说,你应该避免调用GC.Collect,因为它是一个非常CPU密集的进程,在执行操作时会阻塞整个应用程序池。你确定这真的是一个泄漏吗?您正在执行一个必须分配内存的函数,并在循环中这样做。进程内存增加并不意味着它是泄漏。内存永远不会下降吗?我认为我的术语是正确的,内存一直在增长,如果RAM已满,电脑就会重新启动。这是内存泄漏。我已经监视了这个循环大约一个小时。
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();
}