Random photo
Loading...
Domains for sale
|
October 12, 2006XSLT scripting (msxsl:script) in .NET - pure fast evilAnother coding horror story was reported in the microsoft.public.dotnet.xml newsgroup:
Cool. This is just a remainder for those who use XSLT scripting (msxsl:script) in .NET: watch out, this feature can be pure evil if used unwisely - it leaks memory and there is nothing you can do about it. The problem is that when XSLT stylesheet is loaded in .NET, msxsl:script is compiled into an assembly via CodeDOM and then loaded into memory, into the current application domain. Each time the stylesheet is loaded above process is repeated - new assembly is being generated and loaded into the application domain. But it's impossible to unload an assembly from application domain in .NET! Here is KB article on the topic. It says it applies to .NET 1.0 only, but don't be confused - the problem exists in .NET 1.1 and 2.0. Moreover I'm pretty much pessimistic about if it's gonna be fixed in the future. The solution is simple - just don't use script in XSLT unless you really really really have to. Especially on the server side - XSLT script and ASP.NET should never meet unless you take full resonsibility for caching compiled XslCompiledTransform. Use XSLT extension objects instead. Update. Of couse Yuriy reminds me that msxsl:script runs faster than an extension object, because msxsl:script is available at compile time and so XSLT compiler can generate direct calls, while extension objects are only available at run-time and so can only be called via reflection. That makes msxsl:script a preferrable but danger solution when your stylsheet makes lots of calls to extension functions. In a perfect world of course msxsl:script would be compiled into dynamic methods (just like XSLT itself), which are GC reclaimable, but I don't think CodeDOM is capable of doing this currently. I wonder if it's possible to compile C#/VB/J# method source into dynamic method anyway? Also it's interesting how to improve extension objects performance - what if extension objects could be passed at compile time? They are usually available anyway at that time too. Or what if compiled stylesheet could be "JITted" to direct calls instead of reflection? Sergey, Anton, can you please comment on this? Comments
Can you provide more details? If you prefer email, you can contact "oleg" at this domain name. Posted by: Oleg Tkachenko at May 19, 2008 9:10 AMThis is not isolated to script in the xslt's, there's a major bug somewhere in the XslCompiled Transform code. Our site's content all runs through an xslt to clean-up the html created by the content teams. There is NO script in the Xslt's (Only 2 are used for the whole site) and the XslCompiled Transfom has a file dependancy cache on it. Admitedly the problem only ocours when both the GoogleBot and Yahoo Slurp bot handily walk the site at the same time but the 1k-2k exception emails we get as a result is rather irritating!!! If anyone has any ideas how to fix this, other than removing the transforms (Too much work and no time to do it) they'd be very welcome!! Posted by: at May 16, 2008 7:01 PMThanks for the great comment Sergey! I'd not agree that scrip in XSLT is evil. I like the feature. The fact that the implementation of this feature in the .NET Framework 1 & 2 has serious usability problem doesn't mean the feature is bad and can't be implemented better. In the days of MSXML scripts ware slow because they required starting scripting environment to interpret vbscript or jscript. This is quite expensive and extension objects were introduced as workaround. The well known problem with scripts in .NET Framework 2.0 is that the CodeDOM in order to compile scripts generates types and types can be unloaded only with entire AppDomain. The problem is not with the scripts themselves but with luck of adequate technology in .NET to compile them. The script unload problem would not exist if CLR solves the type unloading problem (no evidence that this going to happen soon), or if CodeDOM or some other technology would allow compiling script blocs to dynamic methods (from my perspective C# and Co. compilers should be managed classes that take TextReader as input and write results to the MethodBuilder.). Thus, scripts have chances to overcome the usability problem. Extension objects are unlikely to become better in the way they are designed. In addition I'd like to point to one more victim of script unloading problem: Sergey Posted by: Sergey Dubinets at October 22, 2006 11:41 AMmaxtoroq, doesn't matter which language you are using. Above applies to XslTransform and XslCompiledTransform classes in .NET. Posted by: Oleg Tkachenko at October 18, 2006 12:35 PMDo you know if this apply if you use jscript or javascript as the msxsl:script language? Posted by: maxtoroq at October 18, 2006 5:47 AMGood point, Yuriy! Now I have to update my post. Compare the following call stacks to see the difference how the same function is invoked depending on msxsl:script on XSLT extension object EXTENSION OBJECT: System.Collections.Generic.IList{System.Xml.XPath.XPathItem}[] args) + 0x345 bytes MSXSL:SCRIPT {urn:schemas-microsoft-com:xslt-debug}runtime = {System.Xml.Xsl.Runtime.XmlQueryRuntime}) + 0xc5 bytes
at October 12, 2006 11:04 PM
However, if used carefully msxsl:script provides much value. XSLT compiler generates direct calls to msxsl:script functions while for the XSLT extension objects in generates invokes via reflection API. If you replace calls to EXSLT.NET string handling functions with C# equialents in msxsl:script blocks you get significant performance boost, if they are invoked often. so, if you can manage to cache XSLT compiled instances in memory they are very useful. We dramatically increased performance of the application, by replacing them with msxl:script blocks. It applies to XslCompiledTransform only. Posted by: ysw at October 12, 2006 10:37 PM
Post a comment
|