RazorEngine内存使用情况

时间:2012-09-06 13:45:18

标签: razorengine

我创建了一个用于构建和发送电子邮件的Windows服务。我使用Razor Engine来解析电子邮件模板。我正在使用动态ExpandoObject来创建模型。

我的问题是,当每个电子邮件被创建并发送时,内存正在增加,但它从未被释放。我已经使用Ants Memory分析器(我之前没有使用过这个)来描述该服务,但它显示了以下结果:

使用Razor Engine

使用Razor.Parse(文本,模型)解析200封电子邮件

  

第1代:12.9kb

     

第2代: 15.88mb

     

大对象堆:290.9kb

     

分配给.NET的未使用内存:3.375mb

     

不受管理:69.51mb

     

内存碎片总数:197

没有剃刀引擎

返回200封未经解析的电子邮件。

  

第1代:13.87kb

     

第2代:3.798mb

     

大对象堆:95.58kb

     

分配给.NET的未使用内存:4.583mb

     

不受管理:44.58mb

     

内存碎片总数:7

使用Razor,最大的第2代实例是:

System.Reflection.Emit __FixUpData [] - 2,447,640个实时字节,3,138个实例

有谁知道为什么对象没有被释放而第二代正在增长?有没有办法在每次我想解析模板时都有一个新的RazorEngine实例,当它完成时它将不被引用并将转到GC。

我曾尝试在每次解析模板时创建一个新的Template服务实例,但这并没有产生影响

using (ITemplateService templateService = new TemplateService())
{
     result = templateService.Parse<ExpandoObject>(text, model);
}

4 个答案:

答案 0 :(得分:2)

每次解析模板时,RazorEngine 都会编译内存中的程序集
这可能会变得昂贵。

您应该尽可能多地重复使用模板。

答案 1 :(得分:1)

旧问题,但要激活模板缓存,您必须为Parse方法提供“缓存”参数(可以/应该是模板的路径):

return RazorViewService.Parse(File.ReadAllText(path), model, null, cache);

答案 2 :(得分:0)

编译模板时,创建的动态程序集将加载到当前的appdomain中。没有任何工具可以卸载它们,因此当您编译更多模板时,内存会不断增长。

你可以使用RazorEngine 3.x中的IsolatedTemplateService来解决这个问题。它的作用是将编译后的模板加载到新的appdomain中。当该appdomain被垃圾收集时,也会收集加载到该appdomain中的模板程序集。但是有一些限制 - 例如无法使用动态模型(Expando对象)或匿名模型。该模型还需要可序列化。

从RazorEngine的作者那里看出来:http://www.fidelitydesign.net/?p=473

答案 3 :(得分:0)

如果您使用相同的模板,请重复调用RazorEngine.Compile,然后再调用Razor.Run,​​以确保模板只编译一次。

另外我相信在构建中启用DEBUG时,RazorEngine似乎会泄漏内存。确保您的生产代码是使用Release配置文件构建的,即不使DEBUG编译器保持不变。