Leaking Locale and Core.Local objects?

I am trying to track down a memory leak in a XOJO (2020r2.1) desktop app that causes it to crash after running for several days.
I found some help from Finding memory leak - #4 by Kem_Tekinay and tried implementing a report along the lines suggested by Kem Tekinay of counting ObjectTypes using Interospection.

What I observe is a lot of Objects of type Locale and Xojo.Core.Locale every time I run the report.

I have no idea where these objects are being created. If I search my project in the IDE dont find any words ‘Locale’.

I do use some 3d party Monkeybread plugin for notifications and RubberViews plugins for resizing so I dont know what is inside of those.

See below…
InitialObject count is saved value when I first opened the report window
Current is the count as I hit the RunReport button
LastCount was when I previously hit the button
RecentGrowth is Current-Last
TotalGrowth is The Current-Intital.

As you can see, there is essentially no growth in object counts except for the two “Locale” item types.

Any help in how to track this down is greatly appreciated.

What is your app doing? What happens if your app doesn’t do anything? How long do you need to run your app until you see those locale object showing up?

Have you tried to use Instruments for tracking memory leaks?

Beatrix - Thanks for your response. My application starts up a main window and the user can display as many as five
Other windows. It has a couple of timers that send UDP datagram socket requests to
external servers once per second. When responses are received they are parsed and notifications
are sent to any window or control that has registered to watch for the particular notification
(using the MBS Notificaton classes) Controls typically will display the value they watch, and perform
some test (eg value-in-range, datetime-is-too-old, server-not-found etc). It runs continuously.

The locale objects start showing up immediately… the image above was probably after less than 1 minute.
After the app runs for ~12 hours the count of locale objects has grown from initial object count of 2109
to 69,652,285 and memory has grown from initial 3.2Mb to 1.15Gb

I am going try to follow your article on how to get started with Instruments later today. (To download
and install current xcode I first have to upgrade my mac OS to BigSur - that will be fun Im sure)
I will post back if I can find anything.

Hi Richard.

If you have an Apple developer account check Apple’s Developer website after logging in as you might be able to download an older version of XCode.

You are sure, you don’t stuff them into arrays somewhere?

Can you check if you call locale.current or locale.raw somewhere?
And if yes, what do you do with locale objects? Pass them to framework functions?

Thanks all. Instruments did indeed give me clues. It appears that String.Compare calls are leaving behind Xojo.Core.Locale objects. Ive created a simple test desktop app to demonstrate what I see as the issue.

A single window desktop app with a single button. The button’s Action() event runs the following code every time its pressed. It does 1000 string Compare() calls then counts all of the Xojo.Core.Locale objects it finds and puts up a msgbox. The total count appears to increment by 1000 each time the button is pressed.
Am I doing something incorrectly or is this possibly an issue for TeamXojo to look into?

dim i, j, count as Integer
dim name as String
name = "Anything"

for i  = 0 to 1000
  j = name.Compare("Something")
next i

dim iterator as Runtime.ObjectIterator = Runtime.IterateObjects
count = 0
while iterator.MoveNext
  dim o as object = iterator.Current
  dim ti as Introspection.TypeInfo = Introspection.GetType(o)
  i = ti.FullName.IndexOf("Xojo.Core.Locale")
  if i >= 0 then
    count=count+1
  end if 
wend

msgbox "Found " + Cstr(count) + " Xojo.Core.Local objects"
iterator = nil

If I comment out the string Compare() call there are no locale objects created.

I have a very long running app that does a lot of string comparisons. Perhaps a workaround would be to implement a non-locale string compare function using memory blocks etc.

Thanks for the help everyone.

2 Likes

Please file a bug report with an example project.

This seems to prevent the memory leak. But I am not 100% sure it performs the exact same comparison:

Dim loc As locale = locale.Raw

dim i, j, count as Integer
dim name as String
name = "Anything"

for i  = 0 to 1000
  j = name.Compare("Something", ComparisonOptions.CaseInsensitive, loc)
next I
...
1 Like

Jeremie, Your workaround looks like a fix… I will now try it in my 'real ’ application

Just submitted the bug report.
64642 - String.Compare Leaks Xojo.Core.Locale objects

Thanks - Rich

3 Likes

Thank you for the bug reported.
I added some information to it and an example project (using your code).

I also made two cases:
64646 - Locale.Current should be cached
64647 - Optimize String.Compare to not conver to Text

1 Like

Hi Richard,

That MemoryReport example looks very useful. Is it available as a download?

Regards,

Lee

Lee, Just checked it in at Bitbucket
Please try and report back any issues.

4 Likes

It’s a great project to see how your objects are getting created and destroyed. I found 1 instance where a container control was being leaked very quickly using this tool.

Looks like a great project. First thing I notice: the license file is missing a .txt extension so appears as a Unix executable on Mac. Quick look at the code reveals that the Listbox properties are set on every Timer run (that should not be - just set them in the ListBox Open event), and the RunReport seems to stop updating the listbox after 2 or 3 iterations (memory usage goes up but the displayed stats in the Listbox don’t change). Listbox cells showing possible leaks should probably be shown with red text.

I was going to ask what the license was, but now I see it, thanks.

Markus. Thanks for suggestions - I will try to include some next time Im in there… as for RunReport appears to stop updating… that indicates to me that no new objects visible to the RuntimeObjectIterator have been created since the last run.
dim iterator as Runtime.ObjectIterator = Runtime.IterateObjects
Other things in your apps may be allocating or freeing memory (strings, memblocks, xojo itself) . You can verify for yourself by setting a breakpoint in RunReport the debugger and playing around with it.