Jump to content

Dangling effect instances?


midora

Recommended Posts

I'm not sure if there is a problem maybe someone else likes to check or clarify this.

 

I used my ExamplePropertyBasedEffect class to add output to DebugView in new and dispose.

 

During startup of Paint.NET there is one new and one dispose of the effect instance.

Then there is a second new which has no dispose.

 

Now if I'm just clicking on the menu title 'Effects' there is a new (probably to get the submenu name).

Doing clicking again and again does always a new but no dispose.

 

Clicking on 'Adjustments' does always a new and a dispose.

 

Clicking on other menu titles does no new and dispose.

 

Closing of Paint.NET does not any dispose.

 

Is this an issue with the garbage collector or a dangling / circula reference?

Or may be just issue with understanding?

 

The example project is attached.

 

ExamplePropertyBasedEffect plus instance counter.zip

midoras signature.gif

Link to comment
Share on other sites

For sure that's not the question in this case. Maybe I used the wrong word. The question is why is the destructor not called (a dispose function in my view). It looks like that Paint.NET creates new instances for each effect if you are clicking the menu and never destroys them.

midoras signature.gif

Link to comment
Share on other sites

For sure that's not the question in this case. Maybe I used the wrong word. The question is why is the destructor not called (a dispose function in my view). It looks like that Paint.NET creates new instances for each effect if you are clicking the menu and never destroys them.

 

The garbage collector would only call the destructor to release any unmanaged resources if they have not been released by a call to Dispose (which calls the OnDispose method in the Effect class).

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to comment
Share on other sites

The garbage collector would only call the destructor to release any unmanaged resources if they have not been released by a call to Dispose (which calls the OnDispose method in the Effect class).

 

But this means that - after a while - there may be thousands of unreleased effect instances?

midoras signature.gif

Link to comment
Share on other sites

Ok first, there's no such thing as destructors in managed code. Dispose() methods are not the same thing either.

 

There is a finalizer, which unfortunately in C# has the same syntax as a destructor in C++.

 

You can verify that your object is getting garbage collected with a technique like this,

 

    public class MyClass
    {

        public MyClass() { ... }
 

        ~MyClass() { Debug.WriteLine("Yay I got garbage collected"); } // or use your favorite "debug output" method, even MessageBox.Show() should work here
    }

 

In Paint.NET, a garbage collection is forced whenever the user performs an action that adds to the history (this is not a guarantee for future versions). In general, there is no guarantee that a garbage collection will happen at any given time (from your point of view you should assume that it's non-deterministic), so that's the best way to test this kind of thing.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

OK, that's exactly what the 'finalizer' in the attached example does.

But it is only called for the instance created at startup and for the instances created when I click the Adjustment title.

There are also no calls of the finalizer after an operation which adds a history entry.

 

This is why I did this basic property based example.

 

In the moment I'm developing a so called OptionBasedLibrary with the look and feel of PropertyBased but with some extensions like the possibility to copy/paste and load/save the serialized token to xml, the possibility to create user controls, ...

I solved somehow the issue with CreateInitialToken by using a modified factory pattern which allows to stack a context (scope). Now I'm looking for possible memory issues because I need to construct a context before an effect instance is created (because one of its jobs is to provide language specific texts needed by the base contructor of the effect for name and submenuname). But the memory of the context should be released on deconstruction of the effect.

midoras signature.gif

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...