自定义提取器上的 OutOfMemory
OutOfMemory on custom extractor
我已经将很多小的 XML 文件拼接成一个文件,然后制作了一个自定义提取器到 return 行,每个文件对应一个字节数组。
- 运行 在 remote/master
- 运行 一个文件(gzipped,11Mb),它工作正常。
- 运行它对于多个文件,我得到一个System.OutOfMemoryException。
- 运行 在 local/master
- 运行 它适用于一个或多个文件(gzipped 500+ Mbs),工作正常。
提取器如下所示:
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
{
using (var stream = new StreamReader(input.BaseStream))
{
var xml = stream.ReadToEnd();
// Clean stiched XML
xml = UtilsXml.CleanXml(xml);
// Get nodes - one for each stiched file
var d = new XmlDocument();
d.LoadXml(xml);
var root = d.FirstChild;
for (int i = 0; i < root.ChildNodes.Count; i++)
{
output.Set<object>(1, Encoding.ASCII.GetBytes(root.ChildNodes[i].OuterXml.ToString()));
yield return output.AsReadOnly();
}
yield break;
}
}
错误消息如下所示:
==== Caught exception System.OutOfMemoryException
at System.Xml.XmlDocument.CreateTextNode(String text)
at System.Xml.XmlLoader.LoadAttributeNode()
at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
at System.Xml.XmlDocument.Load(XmlReader reader)
at System.Xml.XmlDocument.LoadXml(String xml)
at Microsoft.Analytics.Tools.Formats.Text.XmlByteArrayRowExtractor.<Extract>d__0.MoveNext()
at ScopeEngine.SqlIpExtractor<ScopeEngine::GZipInput,Extract_0_Data0>.GetNextRow(SqlIpExtractor<ScopeEngine::GZipInput\,Extract_0_Data0>* , Extract_0_Data0* output) in d:\data\ccs\jobs\bc367467-ef86-43d2-a937-46ba2d4cc524_v0\sqlmanaged.h:line 1924
那我做错了什么?我该如何远程调试它?
谢谢!
不幸的是,本地 运行 不强制执行内存分配,因此您必须自己在本地顶点调试中检查内存。
查看上面的代码,我发现您正在将 XML 个文档加载到 DOM。请注意,XML DOM 可以将字符串表示形式的数据大小爆炸到 10 倍或更多(我作为常驻 SQL [的时候见过 2 到 12 XML大师)。
今天每个 UDO 只能获得 1/2 GB 的 RAM 来玩。所以我假设您的 XML DOM 文档开始超出此范围。
通常建议您使用 XMLReader 界面(http://usql.io 上的示例中也有一个 reader 提取器)并扫描文档找到您正在寻找的信息。
如果您的文档总是足够小(例如 <20MB),您可能需要确保释放其他文档的内存并一次操作一个文档。
我们确实有计划允许您使用内存需求来注释您的 UDO,但这仍然有点过时。
我已经将很多小的 XML 文件拼接成一个文件,然后制作了一个自定义提取器到 return 行,每个文件对应一个字节数组。
- 运行 在 remote/master
- 运行 一个文件(gzipped,11Mb),它工作正常。
- 运行它对于多个文件,我得到一个System.OutOfMemoryException。
- 运行 在 local/master
- 运行 它适用于一个或多个文件(gzipped 500+ Mbs),工作正常。
提取器如下所示:
public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
{
using (var stream = new StreamReader(input.BaseStream))
{
var xml = stream.ReadToEnd();
// Clean stiched XML
xml = UtilsXml.CleanXml(xml);
// Get nodes - one for each stiched file
var d = new XmlDocument();
d.LoadXml(xml);
var root = d.FirstChild;
for (int i = 0; i < root.ChildNodes.Count; i++)
{
output.Set<object>(1, Encoding.ASCII.GetBytes(root.ChildNodes[i].OuterXml.ToString()));
yield return output.AsReadOnly();
}
yield break;
}
}
错误消息如下所示:
==== Caught exception System.OutOfMemoryException
at System.Xml.XmlDocument.CreateTextNode(String text)
at System.Xml.XmlLoader.LoadAttributeNode()
at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
at System.Xml.XmlDocument.Load(XmlReader reader)
at System.Xml.XmlDocument.LoadXml(String xml)
at Microsoft.Analytics.Tools.Formats.Text.XmlByteArrayRowExtractor.<Extract>d__0.MoveNext()
at ScopeEngine.SqlIpExtractor<ScopeEngine::GZipInput,Extract_0_Data0>.GetNextRow(SqlIpExtractor<ScopeEngine::GZipInput\,Extract_0_Data0>* , Extract_0_Data0* output) in d:\data\ccs\jobs\bc367467-ef86-43d2-a937-46ba2d4cc524_v0\sqlmanaged.h:line 1924
那我做错了什么?我该如何远程调试它?
谢谢!
不幸的是,本地 运行 不强制执行内存分配,因此您必须自己在本地顶点调试中检查内存。
查看上面的代码,我发现您正在将 XML 个文档加载到 DOM。请注意,XML DOM 可以将字符串表示形式的数据大小爆炸到 10 倍或更多(我作为常驻 SQL [的时候见过 2 到 12 XML大师)。
今天每个 UDO 只能获得 1/2 GB 的 RAM 来玩。所以我假设您的 XML DOM 文档开始超出此范围。
通常建议您使用 XMLReader 界面(http://usql.io 上的示例中也有一个 reader 提取器)并扫描文档找到您正在寻找的信息。
如果您的文档总是足够小(例如 <20MB),您可能需要确保释放其他文档的内存并一次操作一个文档。
我们确实有计划允许您使用内存需求来注释您的 UDO,但这仍然有点过时。