Copied to clipboard

Flag this post as spam?

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


  • Thomas 160 posts 335 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 11280 posts 23678 karma points MVP 11x 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 160 posts 335 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 160 posts 335 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

Please Sign in or register to post replies

Write your reply to:

Draft