9

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

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

使用剃须刀引擎

使用 Razor.Parse(text,model) 解析 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 个实例

有谁知道为什么这些对象没有被释放并且第 2 代正在增长?每次我想解析模板时,有没有办法拥有一个新的 RazorEngine 实例,当它完成时,它不会被引用,而是会进入 GC。

每次解析模板时,我都尝试创建模板服务的新实例,但这并没有什么不同

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

4 回答 4

2

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

return RazorViewService.Parse(File.ReadAllText(path), model, null, cache);
于 2014-03-26T18:03:32.583 回答
2

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

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

于 2012-09-06T13:47:05.323 回答
1

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

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

于 2014-10-08T01:33:00.437 回答
0

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

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

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

于 2012-10-06T23:18:20.070 回答