Memory leaks?

Bug reports.
taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Memory leaks?

Post by taralex » Sat May 16, 2009 11:12 pm

Guys, have you come accross memory leaks when using Ranorex?
I noticed that whenever I use ranorex lib, the memory allocated by my program increases. Then I tried do the following:

Code: Select all

while (true)
{
     //load some big application
     //find some Element inside of it
     //unload this application
}
this automation program runs for 5-6 hours and then blows because of an OutOfMemory exception. The PrivateBytes of the process keep increasing all the time until 1.5 Gig where it blows up.

now I'm not 100% sure it's Ranorex's fault, but the CLR profiler shows that the biggest amount of memory is allocated by the Ranorex library.

that's why I wanted to ask: is there something in Ranorex that I should explicitly dispose of? Haven't found any Dispose() methods in the help...

User avatar
Support Team
Site Admin
Site Admin
Posts: 11710
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Mon May 18, 2009 10:10 am

This could be a problem if the MSAA PlugIn will be heavily used for the automation. We use the COM-Based oleacc.dll from Microsoft internally and we realized that this modul needs a lot of memory in some cases.

You can check this situaliton with your AUT as follows:
  1. Download AccExplorer.exe (Accessibility Explorer 2.0) from the Microsoft homepage
  2. Start your application under test
  3. Start AccExplorer 2.0
  4. Click the finder tool button on the toolbar
  5. Drag the crosshair onto the AUT
  6. Click the "Rebuild Tree" toolbar button several times.
  7. Check the Memory state of AccExplorer and of your AUT
The Ranorex MSAA-PlugIn does the same as the AccExplorer, we read object information from another process with the help of the COM-Object oleacc.dll

If you realize the same effect with AccExplorer, than it's an MSAA issue.

Jenö
Ranorex Team

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Mon May 18, 2009 6:48 pm

Well, using of more memory is not a problem as long as it doesn't keep accumulated.
The problem in my case is that some resources don't get released by the Ranorex library and hence the objects are not claimed by the Garbage Collector.
Try running the code below, in my case the memory size keeps increasing indefinitely.

Code: Select all

using System;
using System.Collections.Generic;
using Ranorex.Core;
using Ranorex;
using System.Diagnostics;
using System.Threading;

namespace MemoryLeakTest
{
    class MemoryLeakTest
    {        
        static void Main(string[] args)
        {
            Console.WriteLine ("Starting memory test");
            MemoryLeakTest.Run();
        }
        private static void Run()
        {
            while (true)
            {
                Test t = new Test();
                t.Load();
                t.FindChildElements(t.ExcelApplication, "a", false); //iterate through all the UI elements                            
                t.ExcelApplication.As<Ranorex.Form>().Close(); //close excel        
                Thread.Sleep(5000);
                Process thisprc = t.GetProcess("MemoryLeakTest");
                Console.WriteLine(thisprc.PrivateMemorySize64); //show how much memory is used by the current process 
                thisprc.Dispose();                
            }
        }       
    }
    public class Test
    {
        Element excelApplication;
        public Element ExcelApplication
        {
            get
            {
                if (excelApplication == null)
                {
                    try
                    {
                        RxPath path = new RxPath("/form[@title='Excel - Book1']");
                        return Host.Local.Element.FindSingle(path, 20000);
                    }
                    catch
                    {
                        Console.WriteLine("Excel window not found.");
                        return null;
                    }
                }
                return excelApplication;
            }
            set
            {
                excelApplication = value;
            }
        }
        public List<Element> FindChildElements(Element parentElement, string accessiblevalue, bool matchexact)
        {
            List<Element> result = new List<Element>();
            Stack<Element> elements = new Stack<Element>(100);
            elements.Push(parentElement);
            while (elements.Count > 0)
            {
                Element currentElement = elements.Pop();
                if (currentElement != null)
                {
                    foreach (Element elem in currentElement.Children)
                    {
                        elements.Push(elem);
                        if (elem.GetAttributeValue("AccessibleValue") != null)
                        {
                            if (matchexact)
                            {
                                if (elem.GetAttributeValue("AccessibleValue").ToString() == accessiblevalue)
                                {
                                    result.Add(elem);
                                }
                            }
                            else
                            {
                                if (elem.GetAttributeValue("AccessibleValue").ToString().Contains(accessiblevalue))
                                {
                                    result.Add(elem);
                                }
                            }
                        }
                    }
                }
            }
            elements.Clear();
            return result;
        }
        public void Load()
        {
            Process exc = Process.Start("excel.exe"); //load excel
            Thread.Sleep(15000);            
            exc.Dispose();                        
        }        
        public Process GetProcess(String ProcessName)
        {
            Process[] processes = Process.GetProcesses();
            for (int x = 0; x < processes.Length; x++)
            {
                if (processes[x].ProcessName == ProcessName)
                    return processes[x];
            }
            return null;
        }
    }
}


User avatar
Support Team
Site Admin
Site Admin
Posts: 11710
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Mon May 25, 2009 4:30 pm

Can you please perform the following steps with Microsoft AccExplorer and inform us about the results:
  1. Download AccExplorer.exe (Accessibility Explorer 2.0) from the Microsoft homepage
  2. Start your application under test
  3. Start AccExplorer 2.0
  4. Click the finder tool button on the toolbar
  5. Drag the crosshair onto the AUT
  6. Click the "Rebuild Tree" toolbar button several times.
  7. Check the Memory state of AccExplorer and of your AUT
This would us help to localize the problem.

Jenö
Ranorex Team

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Wed May 27, 2009 6:52 pm

Oh, I'm sorry, I didn't do it right away.
Yes, indeed, the memory usage of both AUT and AccExplorer 2.0 keep increasing as I press the F5 button in AccExplorer. The number of handles stays the same.

User avatar
Support Team
Site Admin
Site Admin
Posts: 11710
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Tue Jun 02, 2009 3:35 pm

It seems that the spied application does not release the COM objects resulting in not freeing memory used by these objects. Right now, there is not much you can do except for restarting the application once in a while.

We will, however, further investigate this issue and look what we can do to release those internal resources held by the COM objects or at least to minimize the use of COM objects.

Regards,
Alex
Ranorex Support Team