TCriteria is not freed automatically

According to the documentation getting a TCriteria from .Find<> should be freed automatically if I understand correctly. (Aurelius version 5.18.2.2)

I have a situation where this does not seem to happen. I might be doing something wrong, but I unable to see what. Maybe someone can help me out?

var
  lCriteria: TCriteria;
begin
  lCriteria := MyObjectManager.Find<TProjectTool>
      .SubCriteria('ToolConfigID')
        .SubCriteria('FwRelID')
          .SubCriteria('FwID')
          .Where(Linq['Family'] = 'LH');

  MyAureliusDataSet.SetSourceCriteria(lCriteria);

After the above code the MyAureliusDataSet displays the expected records, but when shutting down my application I get a memory leak like this:

21 - 28 bytes: UnicodeString x 1, Unknown x 3
37 - 44 bytes: TList<System.string> x 3, UnicodeString x 1
45 - 52 bytes: TObjectList<Aurelius.Criteria.Base.TSubCriteria> x 3, TObjectList<Aurelius.Criteria.Base.TOrder> x 3, TObjectList<Aurelius.Criteria.Base.TCustomCriterion> x 3
61 - 68 bytes: TCriteria<OneOS.Model.Main.TProjectTool> x 1
77 - 84 bytes: TSubCriteria x 2

If I on the other hand, change the way I get my records to this:

var
  lList: TList<TProjectTool>;
begin
  lList := MyObjectManager.Find<TProjectTool>
      .SubCriteria('ToolConfigID')
        .SubCriteria('FwRelID')
          .SubCriteria('FwID')
          .Where(Linq['Family'] = 'LH')
      .List<TProjectTool>;

  MyAureliusDataSet.SetSourceList(lList, true);

Using the latter approach does not raise an exception when closing my application, so it seem to have cleaned up objects just find.

So question is; am I doing something wrong with my first approach?

The TCriteria object should be destroyed. Can you try to provide a sample project reproducing the issue?

Sure, easiest test that I can think of right now is to use the demo that comes with Aurelius.

I'm using Delphi 12.1 Patch 1, and all latest (per today) TMS BIZ components.

Please open the ..\TMS Aurelius\Demos\Music Library\MusicLibraryVCL.dproj demo project.

Open the View.Albuns.pas file and change the existing code line (Linenumber 84)

Criteria := FManager.Find<TAlbum>.OrderBy('Name');

...with this:

  Criteria := FManager.Find<TAlbum>.OrderBy('Name')
              .SubCriteria('Artist')
              .Where(Linq['Name'] <> 'Just ignore');

Run application and see that it apparently works as expected, but when exiting the application an error is raised (Unexpected Memory Leak).

An unexpected memory leak has occurred. The unexpected small block leaks are:
13 - 20 bytes: TOrder x 1
21 - 28 bytes: UnicodeString x 1, Unknown x 2
37 - 44 bytes: TList<System.string> x 1
45 - 52 bytes: TObjectList<Aurelius.Criteria.Base.TCustomCriterion> x 1, TObjectList<Aurelius.Criteria.Base.TOrder> x 1, TObjectList<Aurelius.Criteria.Base.TSubCriteria> x 1
61 - 68 bytes: TCriteria<MusicEntities.TAlbum> x 1

Thanks for the info.

SubCriteria is tricky, it returns another TCriteria object that represents the sub criteria being created. It's a different object, and that's what you are passing to SetSourceCriteria.

Use this and you should be fine:

 MyAureliusDataSet.SetSourceCriteria(lCriteria.Root);

We will actually do that internally in dataset so your original code will work in next release, but in the meanwhile you can use that as a workaround.

Thank you,
Not a showstopper as there seem to be at least a couple of workarounds.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.