PRB: 不能卸载您创建和使用脚本在 XSLT 中加载的程序集

文章翻译 文章翻译
文章编号: 316775 - 查看本文应用于的产品
本文已归档。它按“原样”提供,并且不再更新。
这篇文章是指以下 Microsoft。NET Framework 类库的命名空间:
  • System.IO
  • System.Xml
  • System.Xml.XPath
  • System.Xml.Xsl
展开全部 | 关闭全部

本文内容

症状

当您使用 System.Xml.Xslt 框架重复使用的<msxsl:script>元素时,内存泄漏可能会出现大量可扩展标记语言 (XML) 或可扩展样式表语言 (XSL) 的应用程序。</msxsl:script>

原因

System.Xml 命名空间支持使用 XSL 转换 (XSLT) 应用程序中使用的脚本元素的嵌入式脚本代码。因此,<msxsl:script>元素允许您选择的编程语言 (如 Microsoft Visual C#。NET 或 Microsoft Visual Basic。NET) 可以执行某些任务。</msxsl:script>

声明的函数包含在脚本块内。在使用嵌入的脚本使用 XSL 文件时,包含 Microsoft 中间语言 (MSIL) 的程序集创建并加载到内存中。由于的设计限制在此版本的 Microsoft。NET 框架中,您无法卸载该程序集从内存。如果创建和重复或在循环中加载的程序集,这可能导致内存泄漏。

解决方案

若要解决此问题,不会重复加载脚本的 XSLT。开发应用程序的方式一次加载 XSLT,并根据需要多次重复使用它。这种做法还可以提高性能。

例如,下面的代码泄漏内存:
For(int i=0;i<1000;i++)
{
      xslt.Load(stylesheet);
      //Do other stuff
      xslt.Transform(doc, null, writer);
}
				
更改一次加载 XSLT 并重用它在循环中,如下所示的代码:
xslt.Load(stylesheet);
For(int i=0;i<1000;i++)
{

      //Do other stuff
      xslt.Transform(doc, null, writer);
}
				
此代码只加载程序集一次,并不会泄露内存。

替代方法

通过卸载包含程序集的所有应用程序域卸载单个程序集。若要这样做,请调用 AppDomain.Unload() 已加载的程序集的每个应用程序域的方法或调用 UnloadDomain() 非托管宿主 API 的方法。

更多信息

再现情况的步骤

  1. 创建可视的 C#。NET 控制台应用程序项目。
  2. 创建 XSLT 应用程序,然后添加以下代码:
    using System;
    using System.IO;
    using System.Xml;
    using System.Xml.XPath;
    using System.Xml.Xsl;
    
    public class Sample
    {
    	private const String filename = "..\\..\\XmlFile1.xml";
    	private const String stylesheet = "..\\..\\XSLTFile1.xslt";
    
    	public static void Main() 
    	{
    
                    for(int i=0;i<1000;i++)
                    {
    
    		XslTransform xslt = new XslTransform();
                    xslt.Load(stylesheet);
    
    		//Load the XML data file.
    		XPathDocument doc = new XPathDocument(filename);
    
    		//Create an XmlTextWriter to write to the console.         
    		XmlTextWriter writer = new XmlTextWriter(Console.Out);
    		writer.Formatting = Formatting.Indented;
    
    		//Transform the file.
    		xslt.Transform(doc, null, writer);
    		writer.Close();
                    }
    		System.Console.Read();
            
    	} 
    }
    					
  3. 创建名为 XSLTFile1.xslt,一个 XSLT 文件,然后添加以下代码:
     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
        xmlns:user="urn:my-scripts">
    
      <msxsl:script language="C#" implements-prefix="user">
    
    <![CDATA[
    
         public double circumference(double radius){
           double pi = 3.14;
           double circ = pi*radius*2;
           return circ;
         }      
                ]] >     
    <!-- Remove the space between ]] and > in the preceding line. -->
    <!-- The space is inserted because of a publishing constraint. -->
    
       </msxsl:script>
    
      <xsl:template match="data">  
      <circles>
    
      <xsl:for-each select="circle">
        <circle>
        <xsl:copy-of select="node()"/>
           <circumference>
              <xsl:value-of select="user:circumference(radius)"/>        
           </circumference>
        </circle>
      </xsl:for-each>
      </circles>
      </xsl:template>
    </xsl:stylesheet>
    					
  4. 创建名为 XMLFile1.xml,一个 XML 文件,然后添加以下代码:
    <?xml version='1.0'?>
    <data>
      <circle>
        <radius>12</radius>
      </circle>
      <circle>
        <radius>37.5</radius>
      </circle>
    </data>
    					
  5. 将 XML 和 XSL 文件保存在应用程序文件夹中。
  6. 单步执行代码。请注意创建和 Visual Studio 在输出窗口中加载程序集。NET。
  7. 打开性能监视器。请注意专用字节内存中显示增加。

属性

文章编号: 316775 - 最后修改: 2014年2月24日 - 修订: 1.0
这篇文章中的信息适用于:
  • Microsoft .NET Framework 4.0
  • Microsoft .NET Framework 2.0
  • Microsoft .NET Framework 1.0
关键字:?
kbnosurvey kbarchive kbprb kbmt KB316775 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 316775
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com