为什么使用XMLReader时从xmltextreaderimpl.initstreaminput中获得OutofMemoryException?

发布于 2025-02-05 21:01:53 字数 5785 浏览 1 评论 0原文

当我尝试读取XML文件并从内部的数据创建对象时, 我不一致(〜100 XML读数中的2个)收到以下错误:

System. OutOfMemoryException: Exception of type 'System. OutOfMemoryException' was thrown.
at System.Xml.XmlTextReaderImpl.InitStreaminput(Uri baseUri. String baseUriStr, Stream stream, Byte/ bytes, Int32 byteCount, Encoding encoding) at System.Xml.XmlTextReaderImpl.FinishinitUriString
at System.Xml.XmlTextReaderImpl..ctor(String uriStr, XmlReaderSetting settings, XmlParserContext context, XmlResolver uriResolver)
at System.Xml.XmlReaderSettings.CreateReader(String inputuri, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputuri, XmlReaderSettings settings, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputUri)

我不确定文件的大小是否重要没有问题的文件。当时正在读取的文件为186KB,为参考,我们处理更大(〜0.5MB)且较小的文件。

该系统的内存比此过程需要的要多得多(8GB)。 我唯一的理论是,在失败时,AV或其他一些过程恰好在使用疯狂的内存。

但是,我很幼稚,XMLTEXTREADER如何消耗记忆,因此也许有一些逻辑上的解释。

这是我用来读取并将XML解析到对象中的代码。

    // Create the list of xml models to be generated
    var xmlModels = new List<Xml_Model>();

    // Read the xml file.
    using (XmlReader reader = XmlReader.Create(xmlPath))
    {
        var endCreate = false;
        var xmlModel = new Xml_Model();
        var isStartDate = false;
        var dateString = string.Empty;
        var entityResult = new Result_Model();
        var dataType = string.Empty;

        // Read each node in turn.
        while (reader.Read())
        {
            // Get the dataType.
            if (reader.Name != string.Empty) dataType = reader.Name;

            // If the value is empty, this is a starting or closing element and we should continue, unless its a special case.
            if (reader.Value == string.Empty || reader.Value.Trim() == string.Empty)
            {
                if (!(reader.Name == "gate_results" || reader.Name == "entity_results"
                                                  || reader.Name == "stop_date"
                                                  || reader.Name == "start_date"))
                    continue;
            }
            
            // Depending on the node type, carry out an operation.
            switch (dataType)
            {
                case "gate_results":
                    // Add the created object to the list, or begin creating a new object.
                    if (endCreate)
                    {
                        endCreate = false;
                        xmlModels.Add(xmlModel);
                    }
                    else
                    {
                        endCreate = true;
                        xmlModel = new Xml_Model();
                    }
                    break;
                case "gate_no": xmlModel.GateNo = reader.Value; break;
                case "operator": xmlModel.TestOperator = reader.Value; break;
                case "test_status": xmlModel.TestStatus = reader.Value; break;
                case "serial_no": xmlModel.SerialNo = reader.Value; break;
                case "f_serial_no": xmlModel.FSerialNo = reader.Value; break;
                case "product_type": xmlModel.ProductType = reader.Value; break;
                case "part_no": xmlModel.PartNo = reader.Value; break;
                case "test_procedure": xmlModel.TestProcedure = reader.Value; break;
                case "start_date": isStartDate = true; break;
                case "stop_date": isStartDate = false; break;
                case "year": dateString += reader.Value; break;
                case "month": dateString += reader.Value; break;
                case "day": dateString += reader.Value; break;
                case "hour": dateString += reader.Value; break;
                case "minute": dateString += reader.Value; break;
                case "second":
                    dateString += reader.Value;
                    if (isStartDate)
                    {
                        xmlModel.StartDate = dateString;
                        dateString = string.Empty;
                    }
                    else
                    {
                        xmlModel.StopDate = dateString;
                        dateString = string.Empty;
                    }
                    break;
                case "result": xmlModel.Result = reader.Value; break;
                case "failure_mode": xmlModel.FailureMode = reader.Value; break;
                case "entity_results":
                    // Add a completed entity result to the list and create a new entity result.
                    if (entityResult.ResultId != 0)
                    {
                        xmlModel.EntityResults.Add(entityResult);
                        entityResult = new Result_Model();
                    }
                    break;
                case "result_id": entityResult.ResultId = int.Parse(reader.Value); break;
                case "key": entityResult.Key = reader.Value; break;
                case "result_desc": entityResult.ResultDesc = reader.Value; break;
                case "entity_no": entityResult.Entity = reader.Value; break;
                case "line_no": entityResult.LineNo = int.Parse(reader.Value); break;
                case "measure_no": entityResult.MeasureNo = int.Parse(reader.Value); break;
                case "measurement": entityResult.Measurement = reader.Value; break;
                case "low_limit": entityResult.LowLimit = reader.Value; break;
                case "high_limit": entityResult.UpperLimit = reader.Value; break;
                case "debug": entityResult.Debug = reader.Value; break;
                default: break;
            }
        }
    }

我已将此代码复制到一个沙盒项目中,并在以前因此错误而失败但无法重复该错误的XML文件上运行了该函数,并且Sandbox Project的总内存使用方式仅在使用指令内部为9.2MB,并且由创建对象的结束使用率为12.3MB。

When I try to read an xml file, and create objects from the data within,
I am inconsistently (2 out of ~100 xml reads) receiving the following error:

System. OutOfMemoryException: Exception of type 'System. OutOfMemoryException' was thrown.
at System.Xml.XmlTextReaderImpl.InitStreaminput(Uri baseUri. String baseUriStr, Stream stream, Byte/ bytes, Int32 byteCount, Encoding encoding) at System.Xml.XmlTextReaderImpl.FinishinitUriString
at System.Xml.XmlTextReaderImpl..ctor(String uriStr, XmlReaderSetting settings, XmlParserContext context, XmlResolver uriResolver)
at System.Xml.XmlReaderSettings.CreateReader(String inputuri, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputuri, XmlReaderSettings settings, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputUri)

I am not sure that the size of the file is important because it would appear that the error is occurring before the file is read, and because I have read larger files without issue. The file that was being read at the time was 186KB and for reference we deal with files that are larger (~0.5MB) and smaller.

The system has a lot more memory than this process should require (8GB).
My only theory that I have is that the AV or some other process happened to be using insane amounts of memory at exactly the time of the failures.

But I am naïve about how the XmlTextReader consumes memory, so maybe there is some logical explanation.

This is the code I am using to read and parse the xml into objects.

    // Create the list of xml models to be generated
    var xmlModels = new List<Xml_Model>();

    // Read the xml file.
    using (XmlReader reader = XmlReader.Create(xmlPath))
    {
        var endCreate = false;
        var xmlModel = new Xml_Model();
        var isStartDate = false;
        var dateString = string.Empty;
        var entityResult = new Result_Model();
        var dataType = string.Empty;

        // Read each node in turn.
        while (reader.Read())
        {
            // Get the dataType.
            if (reader.Name != string.Empty) dataType = reader.Name;

            // If the value is empty, this is a starting or closing element and we should continue, unless its a special case.
            if (reader.Value == string.Empty || reader.Value.Trim() == string.Empty)
            {
                if (!(reader.Name == "gate_results" || reader.Name == "entity_results"
                                                  || reader.Name == "stop_date"
                                                  || reader.Name == "start_date"))
                    continue;
            }
            
            // Depending on the node type, carry out an operation.
            switch (dataType)
            {
                case "gate_results":
                    // Add the created object to the list, or begin creating a new object.
                    if (endCreate)
                    {
                        endCreate = false;
                        xmlModels.Add(xmlModel);
                    }
                    else
                    {
                        endCreate = true;
                        xmlModel = new Xml_Model();
                    }
                    break;
                case "gate_no": xmlModel.GateNo = reader.Value; break;
                case "operator": xmlModel.TestOperator = reader.Value; break;
                case "test_status": xmlModel.TestStatus = reader.Value; break;
                case "serial_no": xmlModel.SerialNo = reader.Value; break;
                case "f_serial_no": xmlModel.FSerialNo = reader.Value; break;
                case "product_type": xmlModel.ProductType = reader.Value; break;
                case "part_no": xmlModel.PartNo = reader.Value; break;
                case "test_procedure": xmlModel.TestProcedure = reader.Value; break;
                case "start_date": isStartDate = true; break;
                case "stop_date": isStartDate = false; break;
                case "year": dateString += reader.Value; break;
                case "month": dateString += reader.Value; break;
                case "day": dateString += reader.Value; break;
                case "hour": dateString += reader.Value; break;
                case "minute": dateString += reader.Value; break;
                case "second":
                    dateString += reader.Value;
                    if (isStartDate)
                    {
                        xmlModel.StartDate = dateString;
                        dateString = string.Empty;
                    }
                    else
                    {
                        xmlModel.StopDate = dateString;
                        dateString = string.Empty;
                    }
                    break;
                case "result": xmlModel.Result = reader.Value; break;
                case "failure_mode": xmlModel.FailureMode = reader.Value; break;
                case "entity_results":
                    // Add a completed entity result to the list and create a new entity result.
                    if (entityResult.ResultId != 0)
                    {
                        xmlModel.EntityResults.Add(entityResult);
                        entityResult = new Result_Model();
                    }
                    break;
                case "result_id": entityResult.ResultId = int.Parse(reader.Value); break;
                case "key": entityResult.Key = reader.Value; break;
                case "result_desc": entityResult.ResultDesc = reader.Value; break;
                case "entity_no": entityResult.Entity = reader.Value; break;
                case "line_no": entityResult.LineNo = int.Parse(reader.Value); break;
                case "measure_no": entityResult.MeasureNo = int.Parse(reader.Value); break;
                case "measurement": entityResult.Measurement = reader.Value; break;
                case "low_limit": entityResult.LowLimit = reader.Value; break;
                case "high_limit": entityResult.UpperLimit = reader.Value; break;
                case "debug": entityResult.Debug = reader.Value; break;
                default: break;
            }
        }
    }

I have copied this code into a sandbox project and ran the function on the xml files that previously failed with this error and could not repeat the error, and the total memory usage for the sandbox project just inside the using directive was 9.2MB and by the end of creating the object the usage was 12.3MB.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文