IDisposable in IronPython

If I am making my own class and I want to be able to call Dispose(), how would I implement that in the ghpython space? Or is Dispose() the wrong approach in IronPython? I feel like I’m going in circles with this.

Here’s what I think it looks like from this little post.

bool disposed = false;
    System.Runtime.InteropServices.SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposed)  return;

      if (disposing) { // only managed objects
        handle.Dispose();        
      }

      // Unmanaged stuff, for example hooked events
      Rhino.RhinoApp.WriteLine(string.Format("(Dispose({0}))", disposing));
      MouseDown_Subscriber(false);   // = "unsubscribe"

      disposed = true;
    }
  } // end class  
} // </Custom additional code> 

I’m not a C# guy and the handle and public/private are throwing me off. not sure how to translate in IronPython.

Can you describe what it is you are trying to do? SafeHandle is an extremely rare class to have to deal with for Rhino/GH development

Thanks, Steve!

We have components that pass custom-authored class instances between compiled ghpython components. When some of the components get refreshed, they take a little (sometimes a lot) longer each time. Each component seems to be storing some data between solutions. The problem is only resolved by restarting Rhino (closing the Grasshopper definition doesn’t seem to do it). I want to be able to Dispose of certain objects within my components and collect the garbage here and there.

Is there maybe a base dot Net class to use for custom classes to inherit that would perform better with data disposal?

IDisposable is a good pattern for deleting resources, but I’m still unsure what these resources are that you want to dispose. All it really does is define a common function that can be called by other code.

Do you know what it is that is causing your system to slow down?

I’m having trouble isolating the slow down. It’s not happening on all the components. Just some of them. My best guess is that when I generate options to solve things that don’t get used, they remain in memory somehow. All I want to do is try to get rid of them with Dispose. I just have not seen an implementation of Dispose in IronPython anywhere. I’d like to try that.

Hi @chrislandau

I’ve seen this type of slowdowns, exactly with garbage-intensive application parts (for example, with dynamic compilation of some IronPython lambdas, that fill memory when created in loops, and especially if they have continuations/variable capture).

My suggestion would be to try to understand which code paths actually cause the slowdowns. You can try disabling some features till the slowdown is gone. Is it possible that memory also increases dramatically when the slowdown happens?

Thanks,

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com

Thanks, Guilio. I’m almost certain it is a memory issue, because when I just reopen Grasshopper file without reopening Rhino, the performance is at the next worse level like I never closed it. And when I run one component multiple times here and then go over to the other component it is multiple factors worse. So it’s remembering something. Not sure what exactly.

Still missing some parts here. Any help would be welcome:

class CustomDisposable(IDisposable):
	def __init__(self):
		self.disposed = false
		# Where to put & how to format this? >>>>
			#System.Runtime.InteropServices.SafeHandle handle = new  
			#SafeFileHandle(IntPtr.Zero, true); 

    def Dispose()
		self.__Dispose(true)
		GC.SuppressFinalize(self)


    def __Dispose(self, disposing):
		if (self.disposed)
			return
		if (disposing)
			handle.Dispose()        
		self.disposed = true

The question I have is what is it that you are trying to dispose? If you don’t know what you need to dispose, there is nothing that implmenting IDisposable will do to help.

Class instances that I am creating that don’t have a dispose function to begin with.

I’ve looked at this from a ton of angles. This seems like a logical move. Just need a little assist. Humor me. :sweat_smile:

Believe me, I am trying to work with you. The thing is that I don’t understand exactly what it is you are trying to dispose of. Unless your classes are consuming unmanaged resources, there is nothing to reclaim with respect to memory. All of Rhino’s GeometryBase derived types do use unmanaged resources, but I’m not sure if you are creating and using these classes

I’m not inheriting any other classes. So I have no idea if my classes which have a wide range of lists and dictionaries and geometries as attributes just hang around every time I make a new copy of them.

You aren’t going to get anything new to happen by implementing IDisposable. If you have a list of geometry hanging around on your object, you can call Dispose() on each piece of geometry when you are done working with it. This will free up memory, but it may not improve performance.

Okay. I appreciate the help. I really do. So there is no point in disposing of class instances that I create?
I also thought disposing of them would help eliminate them from performance drains. Sounds like that is not the case.
Thanks again.

Giulio’s comments above are what I would recommend as well. Try to figure out the components taking the most time. The profiler in Grasshopper is good for this. Once you know which components are taking time let us know and maybe we can help get to the bottom of what is really going on.

1 Like