diff --git a/src/RazorEngine.sln b/src/RazorEngine.sln
index b9fcccdc..b9ad8b5b 100644
--- a/src/RazorEngine.sln
+++ b/src/RazorEngine.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26621.2
+VisualStudioVersion = 15.0.26730.15
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorEngine.Core", "source\RazorEngine.Core\RazorEngine.Core.csproj", "{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}"
EndProject
@@ -98,82 +98,116 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestHelper", "test\TestHelp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestRunnerHelper", "test\TestRunnerHelper\TestRunnerHelper.csproj", "{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestMemory", "test\TestMemory\TestMemory.csproj", "{7E82E3B3-6223-4727-8099-CF4F31D38F10}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
Debug|Net40 = Debug|Net40
Debug|Net45 = Debug|Net45
Debug|Razor4 = Debug|Razor4
+ Release|Any CPU = Release|Any CPU
Release|Net40 = Release|Net40
Release|Net45 = Release|Net45
Release|Razor4 = Release|Razor4
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Debug|Any CPU.ActiveCfg = Debug|Razor4
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Debug|Net40.ActiveCfg = Debug|Net40
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Debug|Net40.Build.0 = Debug|Net40
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Debug|Net45.ActiveCfg = Debug|Net45
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Debug|Net45.Build.0 = Debug|Net45
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Debug|Razor4.ActiveCfg = Debug|Razor4
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Debug|Razor4.Build.0 = Debug|Razor4
+ {D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Release|Any CPU.ActiveCfg = Release|Razor4
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Release|Net40.ActiveCfg = Release|Net40
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Release|Net40.Build.0 = Release|Net40
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Release|Net45.ActiveCfg = Release|Net45
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Release|Net45.Build.0 = Release|Net45
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Release|Razor4.ActiveCfg = Release|Razor4
{D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}.Release|Razor4.Build.0 = Release|Razor4
+ {F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Debug|Any CPU.ActiveCfg = Debug|Razor4
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Debug|Net40.ActiveCfg = Debug|Net40
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Debug|Net40.Build.0 = Debug|Net40
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Debug|Net45.ActiveCfg = Debug|Net45
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Debug|Net45.Build.0 = Debug|Net45
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Debug|Razor4.ActiveCfg = Debug|Razor4
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Debug|Razor4.Build.0 = Debug|Razor4
+ {F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Release|Any CPU.ActiveCfg = Release|Razor4
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Release|Net40.ActiveCfg = Release|Net40
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Release|Net40.Build.0 = Release|Net40
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Release|Net45.ActiveCfg = Release|Net45
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Release|Net45.Build.0 = Release|Net45
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Release|Razor4.ActiveCfg = Release|Razor4
{F4F5AB5F-BF81-4C0C-8F2E-68AB02160C4E}.Release|Razor4.Build.0 = Release|Razor4
+ {878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Debug|Any CPU.ActiveCfg = Debug|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Debug|Net40.ActiveCfg = Debug|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Debug|Net45.ActiveCfg = Debug|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Debug|Net45.Build.0 = Debug|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Debug|Razor4.ActiveCfg = Debug|Net45
+ {878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Release|Any CPU.ActiveCfg = Release|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Release|Net40.ActiveCfg = Release|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Release|Net45.ActiveCfg = Release|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Release|Net45.Build.0 = Release|Net45
{878A8554-ACF1-4A0B-9BFC-6BD5FC5048C4}.Release|Razor4.ActiveCfg = Release|Net45
+ {BC7891A1-8459-4A69-A37C-F40824E28C70}.Debug|Any CPU.ActiveCfg = Debug|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Debug|Net40.ActiveCfg = Debug|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Debug|Net45.ActiveCfg = Debug|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Debug|Net45.Build.0 = Debug|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Debug|Razor4.ActiveCfg = Debug|Net45
+ {BC7891A1-8459-4A69-A37C-F40824E28C70}.Release|Any CPU.ActiveCfg = Release|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Release|Net40.ActiveCfg = Release|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Release|Net45.ActiveCfg = Release|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Release|Net45.Build.0 = Release|Net45
{BC7891A1-8459-4A69-A37C-F40824E28C70}.Release|Razor4.ActiveCfg = Release|Net45
+ {7CB02F9F-7E88-448B-A25B-7985058296C5}.Debug|Any CPU.ActiveCfg = Debug|Razor4
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Debug|Net40.ActiveCfg = Debug|Net40
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Debug|Net45.ActiveCfg = Debug|Net45
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Debug|Net45.Build.0 = Debug|Net45
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Debug|Razor4.ActiveCfg = Debug|Razor4
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Debug|Razor4.Build.0 = Debug|Razor4
+ {7CB02F9F-7E88-448B-A25B-7985058296C5}.Release|Any CPU.ActiveCfg = Release|Razor4
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Release|Net40.ActiveCfg = Release|Net40
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Release|Net45.ActiveCfg = Release|Net45
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Release|Net45.Build.0 = Release|Net45
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Release|Razor4.ActiveCfg = Release|Razor4
{7CB02F9F-7E88-448B-A25B-7985058296C5}.Release|Razor4.Build.0 = Release|Razor4
+ {7899C0AE-844D-4A34-B3BC-96819C73EA68}.Debug|Any CPU.ActiveCfg = Debug|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Debug|Net40.ActiveCfg = Debug|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Debug|Net45.ActiveCfg = Debug|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Debug|Net45.Build.0 = Debug|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Debug|Razor4.ActiveCfg = Debug|Net45
+ {7899C0AE-844D-4A34-B3BC-96819C73EA68}.Release|Any CPU.ActiveCfg = Release|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Release|Net40.ActiveCfg = Release|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Release|Net45.ActiveCfg = Release|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Release|Net45.Build.0 = Release|Net45
{7899C0AE-844D-4A34-B3BC-96819C73EA68}.Release|Razor4.ActiveCfg = Release|Net45
+ {6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Debug|Any CPU.ActiveCfg = Debug|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Debug|Net40.ActiveCfg = Debug|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Debug|Net45.ActiveCfg = Debug|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Debug|Net45.Build.0 = Debug|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Debug|Razor4.ActiveCfg = Debug|Net45
+ {6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Release|Any CPU.ActiveCfg = Release|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Release|Net40.ActiveCfg = Release|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Release|Net45.ActiveCfg = Release|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Release|Net45.Build.0 = Release|Net45
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030}.Release|Razor4.ActiveCfg = Release|Net45
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Net40.ActiveCfg = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Net40.Build.0 = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Net45.ActiveCfg = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Net45.Build.0 = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Razor4.ActiveCfg = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Debug|Razor4.Build.0 = Debug|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Net40.ActiveCfg = Release|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Net40.Build.0 = Release|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Net45.ActiveCfg = Release|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Net45.Build.0 = Release|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Razor4.ActiveCfg = Release|Any CPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}.Release|Razor4.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -192,9 +226,10 @@ Global
{7CB02F9F-7E88-448B-A25B-7985058296C5} = {AE7E811A-2B9F-45BC-9752-0FB4D1DEE12D}
{7899C0AE-844D-4A34-B3BC-96819C73EA68} = {AE7E811A-2B9F-45BC-9752-0FB4D1DEE12D}
{6B0E2ECB-01EE-482B-951C-9E0F0D80F030} = {AE7E811A-2B9F-45BC-9752-0FB4D1DEE12D}
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10} = {AE7E811A-2B9F-45BC-9752-0FB4D1DEE12D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {87BAAA5F-5CFE-4284-91D8-C3C5F4083599}
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.0\lib\NET35
+ SolutionGuid = {87BAAA5F-5CFE-4284-91D8-C3C5F4083599}
EndGlobalSection
EndGlobal
diff --git a/src/source/RazorEngine.Core/Templating/RazorEngineServiceExtensions.cs b/src/source/RazorEngine.Core/Templating/RazorEngineServiceExtensions.cs
index 303536bb..ee88a35b 100644
--- a/src/source/RazorEngine.Core/Templating/RazorEngineServiceExtensions.cs
+++ b/src/source/RazorEngine.Core/Templating/RazorEngineServiceExtensions.cs
@@ -217,11 +217,15 @@ public static void RunCompile(this IRazorEngineService service, string templateS
///
private static string WithWriter(Action withWriter)
{
- using (var writer = new System.IO.StringWriter())
- {
+ // There seems to be something wrong with using a StringWriter when marshalling it to the other AppDomain.
+ // The internal StringBuilder instance inside StringWriter will not get GC:ed until several minutes later,
+ // resulting in OutOfMemoryException on high load. If we use a StreamWriter instead, the problem will go away.
+ var ms = new MemoryStream();
+
+ using (var writer = new StreamWriter(ms))
withWriter(writer);
- return writer.ToString();
- }
+
+ return System.Text.Encoding.UTF8.GetString(ms.ToArray());
}
///
diff --git a/src/test/TestMemory/App.config b/src/test/TestMemory/App.config
new file mode 100644
index 00000000..9d2c7adf
--- /dev/null
+++ b/src/test/TestMemory/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/test/TestMemory/Program.cs b/src/test/TestMemory/Program.cs
new file mode 100644
index 00000000..9a5b4f83
--- /dev/null
+++ b/src/test/TestMemory/Program.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Linq;
+using RazorEngine.Templating;
+
+namespace TestMemory
+{
+ [Serializable]
+ public class TemplateModel
+ {
+ public string Name { get; set; }
+ }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ using (var service = IsolatedRazorEngineService.Create())
+ {
+ service.AddTemplate("TestTemplate",
+ "Hello @Model.Name " + new String(Enumerable.Repeat('A', 100000).ToArray()));
+ service.Compile("TestTemplate", typeof(TemplateModel));
+
+ int counter = 0;
+
+ while (!Console.KeyAvailable)
+ {
+ var result = service.Run("TestTemplate", typeof(TemplateModel), new TemplateModel {Name = "World"});
+ Console.WriteLine("Run: {0}. Result: {1}", ++counter, result.Substring(0, 20));
+ }
+ }
+
+ Console.ReadKey();
+ Console.WriteLine("Key pressed. Press a key again to quit");
+ Console.ReadKey();
+ }
+ }
+}
diff --git a/src/test/TestMemory/Properties/AssemblyInfo.cs b/src/test/TestMemory/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..e96c8f52
--- /dev/null
+++ b/src/test/TestMemory/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TestMemory")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TestMemory")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7e82e3b3-6223-4727-8099-cf4f31d38f10")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/test/TestMemory/TestMemory.csproj b/src/test/TestMemory/TestMemory.csproj
new file mode 100644
index 00000000..12a5d510
--- /dev/null
+++ b/src/test/TestMemory/TestMemory.csproj
@@ -0,0 +1,59 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {7E82E3B3-6223-4727-8099-CF4F31D38F10}
+ Exe
+ TestMemory
+ TestMemory
+ v4.7
+ 512
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {D268F86D-2DAB-4329-A75F-3BCF6D5BCDC4}
+ RazorEngine.Core
+
+
+
+
\ No newline at end of file