.NET内存甚至退出函数后未释放 [英] .NET Memory not freeing up even after exiting the function

查看:122
本文介绍了.NET内存甚至退出函数后未释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些C#code,上面写着一个巨大文件和一些操作后,将其引用为null,退出功能,但是内存不会释放。

I have some C# code that reads a huge file, and after some manipulation, sets its reference to null and exits the function, but the memory won't free up.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
XmlService.ConvertExcelToXML(xmlDoc);
int sdfid = 320;
XmlService.CompareXML(xmlDoc, ref sdfid, pkid);
xmlDoc.RemoveAll();
xmlDoc = null;

xmlDoc中是一个非常大的字符串,通常约为50 MB。当我退出功能,该内存permamnently占用了,我必须重新启动我的服务夫妇,一日2次,否则它的内存使用量达到1GB。

The xmlDoc is a very big string, usually around 50 MB. When I exit the function, that memory is permamnently occupied, and I have to restart my service couple of times a day, otherwise it's memory usage reaches 1GB.

我曾尝试使用GC.Collect的,但没有用。

I have tried to use GC.Collect, but no use.

感谢你在前进。

修改

下面是类声明XmlService。它没有变量。所有的方法都是静态

Here is the class declaration for XmlService. It has no variables. All methods are static

 public class XmlService

ConvertExcelToXML功能的code

ConvertExcelToXML function's code

public static bool ConvertExcelToXML(XmlDocument xmlDoc) {
        XmlNamespaceManager nm = new XmlNamespaceManager(xmlDoc.NameTable);
        nm.AddNamespace("z", "urn:schemas-microsoft-com:office:spreadsheet");
        nm.AddNamespace("o", "urn:schemas-microsoft-com:office:office");
        nm.AddNamespace("x", "urn:schemas-microsoft-com:office:excel");
        nm.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet");
        nm.AddNamespace("html", "http://www.w3.org/TR/REC-html40");
        XmlNodeList rows = xmlDoc.DocumentElement.SelectNodes("//z:Worksheet/z:Table/z:Row", nm);
        if (rows != null && rows.Count > 0)
        {
            XmlNode nodeNames = rows[0];
            XmlNode nodeValues = rows[1];

            XmlNode destRootNode = xmlDoc.CreateNode(XmlNodeType.Element, "ParentNode", null);
            XmlNode fieldNode = null;
            XmlNode dataNode = null;
                for (int i = 0; i < nodeNames.ChildNodes.Count; i++)
                {
                    if (nodeNames.ChildNodes[i].HasChildNodes)
                    {
                        string nodeName = nodeNames.ChildNodes[i].ChildNodes[0].InnerXml;
                        //string nodeValue = nodeValues.ChildNodes[i].ChildNodes[0].InnerXml;
                        string nodeValue = "DataField" + i.ToString();

                        fieldNode = xmlDoc.CreateNode(XmlNodeType.Element, "Field", null);
                        dataNode = xmlDoc.CreateNode(XmlNodeType.Element, "Data", null);
                        dataNode.InnerXml = nodeName;
                        fieldNode.AppendChild(dataNode);
                        destRootNode.AppendChild(fieldNode);

                        fieldNode = xmlDoc.CreateNode(XmlNodeType.Element, "Field", null);
                        dataNode = xmlDoc.CreateNode(XmlNodeType.Element, "Data", null);
                        dataNode.InnerXml = nodeValue;
                        fieldNode.AppendChild(dataNode);
                        destRootNode.AppendChild(fieldNode);
                    }
                }
            xmlDoc.LoadXml("<ParentNode>" + destRootNode.InnerXml + "</ParentNode>");
            return true;
            } 
            return false;

}

和$ C $下CompareXML

and Code for CompareXML

        public static void CompareXML(XmlDocument filexmlDoc, ref int maxSDFID, string PKID)
    {
        FieldsListBO tmpFieldListBO = null;

        ResponseDTO responseDTO = DbService.getConnection();
        DbConnection con = (DbConnection)responseDTO.ReturnedObjects[Constants.CONNECTION_OBJECT];
        DbProviderFactory factory = (DbProviderFactory)responseDTO.ReturnedObjects[Constants.FACTORY_OBJECT];
        DbCommand cmd = factory.CreateCommand();

        cmd.CommandText = "select * from tree_store";
        cmd.Connection = con;
        con.Open();

        DbDataReader dr = cmd.ExecuteReader();
        dr.Read();
        String pXmlizedString = (String)dr["TransactionTree"];
        dr.Dispose();
        cmd.Dispose();
        con.Dispose();
        XmlSerializer xs = new XmlSerializer(typeof(FieldsListBO));
        MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
        XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.ASCII);
        tmpFieldListBO = (FieldsListBO)xs.Deserialize(memoryStream);
        memoryStream.Dispose();
        xmlTextWriter.Close();
        if (tmpFieldListBO.FieldsList.Count < 1)
        {
            maxSDFID = 0;
            return;
        }

        FieldsListBO fieldListBO = new FieldsListBO();

        for (int i = 0; i < tmpFieldListBO.FieldsList.Count; i++)
        {
            if (tmpFieldListBO.FieldsList[i]._pkid.Equals(PKID))
            {
                fieldListBO.FieldsList.Add(tmpFieldListBO.FieldsList[i]);
            }
        }

        GetMaxSDFID(filexmlDoc, ref maxSDFID, fieldListBO);
    }

filexmlDoc被传递给GetMaxSDFID只是被transversed由节点节点没有更新/ delation完成

filexmlDoc being passed to GetMaxSDFID is just being transversed node by node no update/delation is done

推荐答案

我很抱歉地说这一点,我可能是错的,但它的真的看起来的就像你猜测的来源的问题。

I'm sorry to say this, and I could be wrong, but it really looks like you're guessing at the source of the problem.

我说这是因为你试图做的。在清空一个局部变量和,这将解决这个问题的希望调用GC.Collect的。有经验的人会告诉你,这是不是它,也无济于事。

I say this is because of what you tried to do. Nulling out a local variable and calling GC.Collect in the hopes that this will fix it. Experienced people will tell you this isn't it and won't help.

猜测往往是一个很好的方法(例如人已经猜到了 XmlService.ConvertExcelToXML 可能是个问题),但为什么当你不就得了,得到一个猜想该方法的存储器转储当应用程序已经消耗一显著量的存储器。您可以使用 ProcDump 的,但也有很多其他的方法可以做到这一点。

Guessing is often a good approach (for instance others have guessed XmlService.ConvertExcelToXML might be a problem), but why guess when you don't have to, get a memory dump of the process when your application has consumed a significant amount of memory. You can use ProcDump but there are many other ways to do this.

安装 WinDbg的。有了这个工具,你可以分析其与命令的内存转储像!dumpheap -stat ,它可以告诉你到底哪里1 GB是怎么回事。

Install WinDbg. With this tool you can analyze your memory dump with commands like !dumpheap –stat that can tell you exactly where the 1 GB is going.

这篇关于.NET内存甚至退出函数后未释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆