System.OutOfMemoryException Umbraco Recursive Function
Hi,
I am facing a new issue now. I am getting the following in a recursive function where i iterate all the nodes of a specific type with specific values in the properties. For example if you see the following error i got today, happened when the user navigates on a city details page and the system enumerates all the "Things To Do" subarticles of that city. I checked all the nodes of the cities and there is no more than 20 records per city so i think that it is very small amount of nodes to get that type of error.
2015-04-02 13:04:28,462 [10] WARN umbraco.macro - [Thread 121] Error loading MacroEngine script (file: CityRenderer.cshtml, Type: ''. Exception: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at System.Collections.Generic.List`1.set_Capacity(Int32 value) at System.Collections.Generic.List`1.EnsureCapacity(Int32 min) at System.Collections.Generic.List`1.Add(T item) at System.Xml.XPathNodeList.ReadUntil(Int32 index) at System.Xml.XPathNodeList.Item(Int32 index) at System.Xml.XmlNodeList.get_ItemOf(Int32 i) at System.Xml.XmlNode.SelectSingleNode(String xpath) at Umbraco.Core.Configuration.UmbracoSettings.GetKey(String key) at Umbraco.Core.Configuration.UmbracoSettings.get_UseLegacyXmlSchema() at umbraco.NodeFactory.Property..ctor(XmlNode PropertyXmlData) at umbraco.NodeFactory.Node.initialize() at DestinationsHelperFunctions.GetAllNodesByType(List`1& foundNodes, Node node, String typeName, Int32 cityId) at DestinationsHelperFunctions.GetAllNodesByType(List`1& foundNodes, Node node, String typeName, Int32 cityId) at DestinationsHelperFunctions.GetAllNodesByType(Int32 NodeId, String typeName, Int32 cityId) at DestinationsHelperFunctions.GetAllCityReferences(Int32 cityId, String nodeName, Int32 parentNodeId, Int32 amount) at DestinationsHelperFunctions.GetThingsToDo(Int32 cityId, Int32 amount) at ASP._Page_macroScripts_CityRenderer_cshtml.Execute() in c:\inetpub\vhosts\arttravel.gr\httpdocs\Umbraco-v6\MacroScripts\CityRenderer.cshtml:line 105 at System.Web.WebPages.WebPageBase.ExecutePageHierarchy() at System.Web.WebPages.WebPage.ExecutePageHierarchy(IEnumerable`1 executors) at System.Web.WebPages.WebPage.ExecutePageHierarchy() at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) at umbraco.MacroEngines.RazorMacroEngine.ExecuteRazor(MacroModel macro, INode currentPage) at umbraco.MacroEngines.RazorMacroEngine.Execute(MacroModel macro, INode currentPage) at umbraco.macro.loadMacroScript(MacroModel macro) at umbraco.macro.renderMacro(Hashtable pageElements, Int32 pageId)
Do you have some code that could be shared? And how does the user pick a city/article? Perhaps the issue happens because one of the children looped over does not have an id picked.
if (null != foundNodes) return foundNodes; else return new List<Node>(); }
And from this function starts the recursive mode:
private static List<Node> GetAllNodesByType(int NodeId, string typeName, int cityId) { List<Node> foundNodes = new List<Node>(); var node = new Node(NodeId);
foreach (Node childNode in node.Children) { var child = childNode; if (child.NodeTypeAlias == typeName) { try { if (child.HasProperty("city") && child.GetProperty("city") != null) { var city = child.GetProperty("city").Value; if (null != city) { string[] arr = city.Split(','); if (null != arr && arr[arr.Length - 1].InvariantEquals(cityId.ToString())) { foundNodes.Add(child); } } } } catch (Exception ex) { string ss = ex.Message; } }
if (child.Children.Count > 0) GetAllNodesByType(ref foundNodes, child, typeName, cityId); }
This code is working for at least one year. I believe that the OutOfMemory has to do with the memory leaks of the MailEnable Server (which have memory leaks) but i need a suggestion if there is a better way to try and get the results instead of doing the recursive model.
System.OutOfMemoryException Umbraco Recursive Function
Hi,
I am facing a new issue now. I am getting the following in a recursive function where i iterate all the nodes of a specific type with specific values in the properties. For example if you see the following error i got today, happened when the user navigates on a city details page and the system enumerates all the "Things To Do" subarticles of that city. I checked all the nodes of the cities and there is no more than 20 records per city so i think that it is very small amount of nodes to get that type of error.
2015-04-02 13:04:28,462 [10] WARN umbraco.macro - [Thread 121] Error loading MacroEngine script (file: CityRenderer.cshtml, Type: ''. Exception: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Collections.Generic.List`1.set_Capacity(Int32 value)
at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
at System.Collections.Generic.List`1.Add(T item)
at System.Xml.XPathNodeList.ReadUntil(Int32 index)
at System.Xml.XPathNodeList.Item(Int32 index)
at System.Xml.XmlNodeList.get_ItemOf(Int32 i)
at System.Xml.XmlNode.SelectSingleNode(String xpath)
at Umbraco.Core.Configuration.UmbracoSettings.GetKey(String key)
at Umbraco.Core.Configuration.UmbracoSettings.get_UseLegacyXmlSchema()
at umbraco.NodeFactory.Property..ctor(XmlNode PropertyXmlData)
at umbraco.NodeFactory.Node.initialize()
at DestinationsHelperFunctions.GetAllNodesByType(List`1& foundNodes, Node node, String typeName, Int32 cityId)
at DestinationsHelperFunctions.GetAllNodesByType(List`1& foundNodes, Node node, String typeName, Int32 cityId)
at DestinationsHelperFunctions.GetAllNodesByType(Int32 NodeId, String typeName, Int32 cityId)
at DestinationsHelperFunctions.GetAllCityReferences(Int32 cityId, String nodeName, Int32 parentNodeId, Int32 amount)
at DestinationsHelperFunctions.GetThingsToDo(Int32 cityId, Int32 amount)
at ASP._Page_macroScripts_CityRenderer_cshtml.Execute() in c:\inetpub\vhosts\arttravel.gr\httpdocs\Umbraco-v6\MacroScripts\CityRenderer.cshtml:line 105
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.WebPages.WebPage.ExecutePageHierarchy(IEnumerable`1 executors)
at System.Web.WebPages.WebPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at umbraco.MacroEngines.RazorMacroEngine.ExecuteRazor(MacroModel macro, INode currentPage)
at umbraco.MacroEngines.RazorMacroEngine.Execute(MacroModel macro, INode currentPage)
at umbraco.macro.loadMacroScript(MacroModel macro)
at umbraco.macro.renderMacro(Hashtable pageElements, Int32 pageId)
Umbraco Version 6.2.3
Any suggestions please?
Hi Thomas
Do you have some code that could be shared? And how does the user pick a city/article? Perhaps the issue happens because one of the children looped over does not have an id picked.
/Jan
Following is the function which is called from the macroscript CityRenderer.cshtml
public static List<Node> GetThingsToDo(int cityId, int amount = 0)
{
List<Node> foundNodes = GetAllCityReferences(cityId, "DESTINATIONS - THINGS TO DO", 4232);
if (null != foundNodes && foundNodes.Count() > 0)
{
return foundNodes.OrderBy(m => m.GetProperty("title").Value).ToList();
}
else
return new List<Node>();
}
This function calls as you can see the GetAllCityReferences function which is the following:
private static List<Node> GetAllCityReferences(int cityId, string nodeName, int parentNodeId = 0, int amount = 0)
{
List<Node> foundNodes = new List<Node>();
Node parentNode = null;
if (parentNodeId == 0)
{
parentNode = umbraco.uQuery.GetNodesByName(nodeName).SingleOrDefault();
}
else
{
parentNode = new Node(parentNodeId);
}
if (null != parentNode)
{
foundNodes = GetAllNodesByType(parentNode.Id, "travelDestinationType", cityId);
}
if (amount > 0 && null != foundNodes && foundNodes.Count() > 2)
return foundNodes.OrderByDescending(f => f.UpdateDate).Take(amount).ToList();
if (null != foundNodes)
return foundNodes;
else
return new List<Node>();
}
And from this function starts the recursive mode:
private static List<Node> GetAllNodesByType(int NodeId, string typeName, int cityId)
{
List<Node> foundNodes = new List<Node>();
var node = new Node(NodeId);
foreach (Node childNode in node.Children)
{
var child = childNode;
if (child.NodeTypeAlias == typeName)
{
try
{
if (child.HasProperty("city") && child.GetProperty("city") != null)
{
var city = child.GetProperty("city").Value;
if (null != city)
{
string[] arr = city.Split(',');
if (null != arr && arr[arr.Length - 1].InvariantEquals(cityId.ToString()))
{
foundNodes.Add(child);
}
}
}
}
catch (Exception ex)
{
string ss = ex.Message;
}
}
if (child.Children.Count > 0)
GetAllNodesByType(ref foundNodes, child, typeName, cityId);
}
return foundNodes.OrderByDescending(m => m.UpdateDate).ToList();
}
This code is working for at least one year. I believe that the OutOfMemory has to do with the memory leaks of the MailEnable Server (which have memory leaks) but i need a suggestion if there is a better way to try and get the results instead of doing the recursive model.
Regards
Thomas
is working on a reply...