Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Thomas 151 posts 326 karma points
    Apr 02, 2015 @ 14:48
    Thomas
    0

    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?

  • Jan Skovgaard 11258 posts 23500 karma points MVP 7x admin c-trib
    Apr 03, 2015 @ 16:23
    Jan Skovgaard
    0

    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

  • Thomas 151 posts 326 karma points
    Apr 03, 2015 @ 16:35
    Thomas
    0

    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();
        }

  • Thomas 151 posts 326 karma points
    Apr 03, 2015 @ 16:37
    Thomas
    0

    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

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies