ReleaseObj vs ReleaseMts/ReleaseClf in .net

Hello,

a quick question on how to release the different types of CVB objects.

As far as I am aware for Cvb.Image.IMG it is advised to use Cvb.Image.ReleaseObj.

If you create a Minos classifier or training-set, can you call Cvb.Image.ReleaseObj or do you need to call the specific functions such as Cvb.Minos.ReleaseClf(ref clf)/ReleaseMTS? Would it be even possible to use Cvb.Image.ReleaseObj without parsing the object?

Thank you for your help.

Have a nice weekend.

Hi @Amicelli!

Correct. Cvb.Image.ReleaseObj will call the CVCImg.dll function ReleaseObject, which is what you want to do in order to free the memory occupied by your image object (once its reference count goes down to zero…). Using its sibling function Cvb.Image.ReleaseObject from iCVCImg.dll is discouraged and will emit a warning because when we switched from value type Cvb.Image.IMG handles to reference type Cvb.Image.IMG handles in :cvb: 11.0 the old semantics of nullifying the input handle like the C-API function ReleaseObject does did not work any more. ReleaseImage should not be used any more - for reasons why it’s still around see the next blur spoiler…

That question cannot be answered without taking a look at the :cvb: version you are using. Prior to :cvb: 13, calling the appropriate release function - ReleaseMts for your MTS, ReleaseClf for Minos classifiers and so on - was mandatory. Failure to do so would result in a resource leak, failure to call the correct function would result in undefined behavior. The reason for this lies in the implementation, which originally was done in Delphi. With ReleaseObject being implemented in C and the objects in the Delphi implementation not sharing a commonly usable vtable interface it was not reasonably possible to release the MinosCVC.dll’s Delphi objects from within ReleaseObject and therefore they needed their own release function (and in case you’re wondering why every object had its own release function read the next blur spoiler…).

In more recent versions of :cvb: this was cleaned up and today (:cvb: 13.01.xxx) only one tool remains that requires you to call object-specific release functions: Manto (and as Manto has been made redundant by the introduction of Polimago this is unlikely to change in the foreseeable future). For all the other tools that are using reference counted object - Minos, Polimago, ShapeFinder, some parts of the Foundation Package - the rule is that you can pass any of these object handles directly to ReleaseObject (and when I say ReleaseObject I mean the function exported by CVCImg.dll which maps to the iCVCImg.dll’s Cvb.Image.ReleaseObj function). In fact all the object-specific release functions (which are kept around in order to not break code compatibility) will internally simply invoke ReleaseObject.

Now, why do we have this whole zoo of release functions to begin with? Much of the original implementation of :cvb: - not just most of the tools but also much of the Image Manager - was done in Delphi and in fact in the first versions (up to 7.2) there simply only was ReleaseObject. In that version it turned out that Delphi 4’s memory manager for list objects (many of the :cvb: reference counted objects were effectively based on list objects) had a problem in multi threaded applications and needed to be swapped for a thread-safe version. With this change the multithreading issues were sorted out, but reliably releasing reference counted objects now required the release function to know what object it was dealing with - a requirement that had not been part of the contract of ReleaseObject. This is why back in 2001/2002 all the ReleaseXXX (and ShareXXX) functions appeared in :cvb: 7.2.1.
The gradual move to a C/C++ code base and vtable interfaces for all reference counted objects made these specialized Share and Release functions obsolete, but it was decided to leave them in the API because removing them would have broken backward compatibility.

2 Likes

Thank you @illusive for the explanation. This makes sense :grinning:

Hello @illusive,

one last question on this topic (CVB version 12.xxx/ .net c#). As far as I understand, basically all classifiers and mts objects need to be cleaned up after its use. However, how does it look like for the Cvb.Minos.MTSMODEL?

Cvb.Minos.MTSMODEL mtsModel = Cvb.Minos.GetMTSModel(minosMTS, 0);

I cannot see a function which would allow to clean up the memory. Does it need to be cleaned up?

Thanks.

Hi @Amicelli,

this is one of luckily not too many unfortunate exceptions to the rule. Cvb.Minos.GetMTSModel() returns a handle to an MTSMODEL object without modifying the reference count of the training set or the model involved! Therefore you may call this function all day long - no corresponding Release call will be required (which is also the reason why there never was a matching Release function for these objects).

Nevertheless, MTSMODEL objects are in fact true reference counted object, and you could, in principle, call ReleaseObject from the CVCImg.dll on them. But trust me: nothing good will come from that :slight_smile:

The same applies to the following functions:

  • Cvb.Minos.GetImageFromImage()
  • Cvb.Minos.GetImageFromInstance()
  • Cvb.Minos.GetImageFromModel()
  • Cvb.Minos.GetModelFromInstance()
  • Cvb.Minos.GetMTSFromImage()
  • Cvb.Minos.GetMTSFromInstance()
  • Cvb.Minos.GetMTSFromModel()
  • Cvb.Minos.GetMTSImage()
  • Cvb.Minos.GetMTSInstance()
  • Cvb.Minos.Teach.MTSImageInstance()
  • Cvb.Minos.Teach.MTSModelInstance()

Hint: Since version 13.0 the MinosDLLReference.chm does a better job at hinting at these peculiarities; for example the documentation for MTSModel (which is the unmanaged counterpart for Cvb.Minos.GetMTSModel()) now says:

Thank you very much for the detailed information. Very helpful :slight_smile: