ColorGrid not releasing memory?

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

ColorGrid not releasing memory?

Post by Joakim » Fri Oct 22, 2010 10:17 am

Hi

We have a serious memory problem with the Colorgrid in our application.

We have Form with a usercontrol that contains a colorgrid series with lots of data, but when we close the form that holds the colorgrid the memory is not released back to the OS it seems if you have task manager open simultaneously you can see this.

So after you have opened and closed this form (to analyse different data) a couple of times the application will raise a System out of memory exception. The memory is released back to the OS when the application closes.

I have created a vs2010 solution (attached) which kind of simulates the problem we are experiencing.

Best regards,
Joakim.
Attachments
MemoryT.zip
(143.38 KiB) Downloaded 1398 times

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: ColorGrid not releasing memory?

Post by Sandra » Fri Oct 22, 2010 1:48 pm

Hello Joakim,

Thank you for your code. Please notice that the .NET Framework doesn't free objects immediately, it's garbage collector who does that task. Therefore, deterministic finalization is not available in .NET Framework as it's explained here:

http://www.geekinterview.com/question_details/5532
http://stackoverflow.com/questions/1884 ... ation-in-c

Also, I have found different pages where it's explained how to force garbage collection. Please see here:

http://stackoverflow.com/questions/2335 ... ction-in-c
http://www.developer.com/net/csharp/art ... in-NET.htm

If you prefer VB information:

http://www.java2s.com/Code/VB/Developme ... ection.htm
http://www.vb-helper.com/howto_net_force_gc.html

I recommend you to use form's Closed event, I think that is the best option :).

I hope will helps.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

Re: ColorGrid not releasing memory?

Post by Joakim » Fri Oct 29, 2010 12:32 pm

Hi Sandra

Thank you for your reply
I have a pretty good understanding of how the memory and garbage colletion works in .NET.

I have investigated this problem a lof since my last post and I am now 99% sure that the problem is because of this code :

Code: Select all

Dim oMarkTipTool As New Steema.TeeChart.Tools.MarksTip(m_Ctrl.Chart(i).Chart)
      oMarkTipTool.Style = Steema.TeeChart.Styles.MarksStyles.XY
      m_MarkTip.Add(oMarkTipTool)
If I add a marktip to the teechart control, the memory is lost forever(~300meg) until I close the applciation and start it again.
Furhtermore, this problem ONLY occurs if I actually move the mouse over the Teechart and a marktip is actually displayed. It does not matter what kind of Idiposable pattern, best practices for memory management I throw at it, the memory is simply lost.

If I choose to not at the marktip, no problem. If I add the marktip but do not move the over the teechart, no problem.

I have tried with clearing the tools list of the teechart and also disposing each tool manually, nothing helps.
Unfortunately I have not been able to reproduce the problem in example code, and the code I sent earlier does not show the problem I am experiencing.

Greatful for any assistance or tip I can get,

Best regards,
Joakim.

Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

Re: ColorGrid not releasing memory?

Post by Joakim » Fri Oct 29, 2010 3:07 pm

Sorry, I missed some letters, what I meant to say was :

"If I choose to not add the marktip, no problem. If I add the marktip but do not move the mouse over the teechart, no problem."

Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

Re: ColorGrid not releasing memory?

Post by Joakim » Mon Nov 01, 2010 8:36 am

Hi Sandra

I have now created a new test solution which is attached. This clearly shows that memory is never reclaimed, the first code example I provided did not show this.

It has something to do with the form being an mdichild. In the attached example, there are four buttons. If the form is opened as Mdichild and a marktip is added to the colorgrid series, then memory is gone. In all other cases, if opened as a non-mdichild or if opened without adding the marktip, problem is not there. Clicking the first button, if you have task manager open, you can see that the memory is growing and growing and never released back.

Please get back to me as soon as possible,
Best regards,
Joakim.
Attachments
MemoryStealer.zip
(95.43 KiB) Downloaded 1366 times

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: ColorGrid not releasing memory?

Post by Narcís » Tue Nov 02, 2010 12:08 pm

Hi Joakim,

Find attached an example project which doesn't use TeeChart. Compiling it in release mode and running the exe, both MDI forms allocate memory when running and don't free them when they are closed. Moreover, their consumption increases as mouse moves over them. This is the same behaviour we get with your application. Can you reproduce this? Do you see any difference between the application that uses TeeChart and the application that doesn't?

Thanks in advance.
Attachments
MemoryThief_II.zip
(17.44 KiB) Downloaded 1357 times
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

Re: ColorGrid not releasing memory?

Post by Joakim » Wed Nov 03, 2010 6:04 am

Hi Narcis

Thank you for getting back to me.

Yes I see a clear difference in the example you provided and the example I have provided. This happens only with TeeChart as I can see.

I am afraid I am not explaining myself properly so to be very clear :

Fire up my example application MemoryStealer.zip

1. Press the button "Open as MdiChild with Marktip". (The form with the colorgrid will now open)
2. Close the form that has just opened.
3. Now repeat steps 1-2 three more times times. (yes, open and close the form three more times).
4. Fire up your task manager, switch to the tab processes and choose to sort the list by memory. Our memory test application should now consume approximately 500 megabytes of memory.

Now, normally what will happen after the Garbage collector in .NET has done it's stuff is that memory that no longer is used will be freed and released back to the operating system, but it does not. You can wait for minutes, hours and the memory will not be released
Of course, when trying to find problems we don't wanna sit around and wait for the Garbage collector to do it's job, so I've added a Force garbage button in order for us to be able to really force the initiation of the garbage collection.

5. Press the force garbage button a few times. If you after this look at task manager, you will see that our memory in task manager is still very close to 500 megabytes.

Now stop and restart our memorystealer application.Follow the same procedure as described in 1 to 5 above, but do it for the other three buttons I have created "Open as MdiChild without Marktip", "Open as StandAlone with Marktip" and "Open as StandAlone without Marktip". You will discover that for all these three buttons, that memory will pop down to about 150 megabytes when you force the garbage collection. You can open and close the form how many times you like with these buttons cause as soon as the garbage collector does its magic, memory sinks down to 150 megs again.

I have spent a lot of time trying to solve this problem for our customers and I finally realized that I can't without your help.

If you are able to see the problem that I am trying to describe, I can also add that this only happens, if the mouse at some point is actullay moved over the teechart and the Marktip is "Used".
If you are not able to see the problem I am trying to describe, I will be happy to setup a WebEx session (Like remote desktop with viewing priviliges) where i can demonstrate the problem for you. If you would like me to do that, send me a private message and we can agree upon a time.

Why is this a problem for our customers? Eventually after using our application some time they will receive a system.outofmemoryexception.

Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

Re: ColorGrid not releasing memory?

Post by Joakim » Wed Nov 03, 2010 7:23 am

I am actullay unsure if this forum have the capability of sending private messages. If not, you can contact me at : joakim dot bergstrom at skf dot com

Christopher
Site Admin
Site Admin
Posts: 1349
Joined: Thu Jan 01, 1970 12:00 am
Location: Riudellots de la Selva, Catalonia
Contact:

Re: ColorGrid not releasing memory?

Post by Christopher » Wed Nov 03, 2010 1:26 pm

Hi,

I'm the lead developer on TeeChart for .NET. Nice to meet you.

I've been able to reproduce your issue here. I don't think that it's entirely a TeeChart problem. That does not mean to say that I'm not prepared to help you out :)

The reason I don't think that it's a TeeChart problem is that I can reproduce everything you report in an mdi application that does not reference TeeChart. Such an example application was posted by Narcís in this thread called MemoryThief_II.zip.

I'm using the Windows Task Manager under Windows 7. Under the Performance tab there's a "Resource monitor..." button. Using this resource monitor I can see exactly how much memory Windows is committing to any given application. If I run the MemoryThief_II example in release mode I can see this application in the resource monitor. When I open mdi child forms in this example, the Commit memory increases for each child form opened and does not decrease when the child form is closed. This is exactly what you are getting with the TeeChart application. I further added a "Force Collect" button to this example with identical code to your one. Pressing this button has absolutely no effect on the Commit memory having opened and closed three or four mdi child forms, again in a very similar fashion to what you are getting in the TeeChart application.

To my mind, this means that there is a memory leak within the framework. This suspicion of mine was confirmed by this google search:
http://www.google.com/search?q=mdi+form ... +leak+c%23

you will be able to read several stories of developers who have found memory leaks with mdi child forms in very similar situations. One proposed solution was to add the following code to the mdi parent form:

Code: Select all

   protected override void OnMdiChildActivate(EventArgs e)
    {
      base.OnMdiChildActivate(e);
      try
      {
        typeof(Form).InvokeMember("FormerlyActiveMdiChild",
        BindingFlags.Instance | BindingFlags.SetProperty |
        BindingFlags.NonPublic, null,
        this, new object[] { null });
      }
      catch (Exception)
      {
        // Something went wrong. Maybe we don't have enough
        // permissions to perform this or the
        // "FormerlyActiveMdiChild" property no longer
        // exists.
      }

    }
this code *seems* to reduce the amount of memory Windows commits to the mdi application. Opening and closing mdi child forms does not *seem* to produce the same sort of increases in Commit memory as does running the example application without this code in it. However, forcing a garbage collection still does not reduce the Commit memory of the application even when this code is used.

Can you possibly see why I might think that the problem you are experiencing is not entirely due to TeeChart?
Thank you!

Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/

Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

Re: ColorGrid not releasing memory?

Post by Joakim » Thu Nov 04, 2010 7:07 am

Dear Christopher

Thank you for getting back to me and posting the information you found about the memory leaks in .NET :)
I have seen some information regarding this already, and I have already tried applying the solution that is provided, to set the property "FormerlyActiveMdiChild" to Null. If you want to try it in my solution I have provided to you, use the following vb.net syntax:

Code: Select all

 Protected Overrides Sub OnMdiChildActivate(ByVal e As System.EventArgs)
    MyBase.OnMdiChildActivate(e)
    Try
      GetType(Form).InvokeMember("FormerlyActiveMdiChild", +Reflection.BindingFlags.Instance + Reflection.BindingFlags.NonPublic + Reflection.BindingFlags.SetProperty, Nothing, Me, New Object() {Nothing})
    Catch ex As Exception
      Debug.Print("Ooppss")
    End Try
  End Sub
Unfortunately this does not help anything.

In the MemoryThief_II.zip solution kindly provided by Narcis, my problem that I am experiencing is not reproduced. To show this more clearly, Change the code of the usercontrol to:
in the memoryThief_II solution to :

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace TestControl
{
  public partial class UserControl1 : UserControl
  {
    public UserControl1()
    {
      InitializeComponent();
      Array.Resize(ref TestArray, 100000000);
      for (int i = 1; i < 100000000; i++)
      {
          TestArray[i] = 1;
      }
   }

    protected override void OnPaint(PaintEventArgs e)
    {
      Draw(e.Graphics);
       
    }

    private SolidBrush _brush;
    private byte[] TestArray;
    public SolidBrush Brush 
    {
      get
      {
        if(_brush == null) _brush = new SolidBrush(Color.Red);
        return _brush;
      }
    }

    private void Draw(Graphics g)
    {
      Rectangle rect = ClientRectangle;
      Brush.Color = Color.Red;
      g.FillRectangle(Brush, rect);
    }
  }
}

Also add a Force Garbage collection button to your Mdiform :

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace MemoryTest2
{
  public partial class MDIParent1 : Form
  {
    public MDIParent1()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      MemStealer form = new MemStealer();
      form.MdiParent = this;
      form.Show();
    }

    private void button2_Click(object sender, EventArgs e)
    {
      MemStealer form = new MemStealer();
      form.Show();
    }

    private void button3_Click(object sender, EventArgs e)
    {
        GC.Collect();
        GC.SuppressFinalize(this);
        GC.Collect();
        GC.SuppressFinalize(this); 
    }
  }
}
Now when we run memorystealer II solution and open up the task manager, we will see that the memory is growing and growing with approximately 100 megabytes each type we open
the mdichild form. However, if we choose to open for example 5 forms and then close them, regardless of opening the forms as MdiChild or not, the memory will always go down to about 100 megabytes or less
after pressing the force garbage collection button a few times which is perfectly fine. This is great ! This is the exact thing that happens in my application on the other three buttons I have, but not for the button where I open the form as mdichild with marktip.

You could be right, this problem could very well be of a bug in the .net framework, and of course I understand that this is your first priority when investigating a case like this, is this really a teechart problem or not?
Maybe it is a combination of teechart and .net framework. However the fact remains, if I add the marktip to our "real" application, the application will run out of memory, if I don't the application runs just fine.

Let me ask you this, can you or can you not see a difference between the button "Open as MdiChild with Marktip" and the other three buttons regarding memory consumption in my test application?

Best regards,
Joakm

Christopher
Site Admin
Site Admin
Posts: 1349
Joined: Thu Jan 01, 1970 12:00 am
Location: Riudellots de la Selva, Catalonia
Contact:

Re: ColorGrid not releasing memory?

Post by Christopher » Thu Nov 04, 2010 2:41 pm

Joakm,
Joakim wrote: Let me ask you this, can you or can you not see a difference between the button "Open as MdiChild with Marktip" and the other three buttons regarding memory consumption in my test application?
Yes, I can. I was also able to reproduce a similar problem with a ToolTip using the test project we've been talking about. Thanks to that test I think I may have a partial solution.

Please have a go with the TeeChart.dll here. The password to the zip file is the same as the password of your license. This TeeChart.dll was built in VS2010 with the .NET 2.0 Framework targetted.

Here, using this TeeChart.dll, at least the memory is released when we force garbage collection. That's the best I can do for now, I'm afraid.
Thank you!

Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/

Joakim
Newbie
Newbie
Posts: 8
Joined: Thu Mar 04, 2010 12:00 am

Re: ColorGrid not releasing memory?

Post by Joakim » Thu Nov 04, 2010 3:13 pm

Hi Christopher

Thank you. I will try the .dll you have provided.

I have investigated more, and I also think that a bug in the .net framework (with the tooltip) is causing the problem in teechart.

Post Reply