Page 1 of 1

Memory Leaks

Posted: 03 Apr 2025, 13:28
by Tomas
Hi,
How can I use TRACK_ALIVE_OBJECTS to search for memory leaks?

Re: Memory Leaks

Posted: 03 Apr 2025, 20:43
by Tomas
in the Noesis debugging build, on the call Noesis::Shutdown() I get the log

NOESIS[E]: Assertion failed: gFaceCache.Empty(), at VGLFontFace.cpp(294).
NOESIS: Noesis Shutdown.
NOESIS[W]: Memory leaks detected: 232560 bytes.
NOESIS: Enable 'TRACK_ALIVE_OBJECTS' in BaseObject.cpp to get more information.
NOESIS: Enable 'CRTDBG_LEAK_CHECK' in Memory.cpp to get more information.

Re: Memory Leaks

Posted: 04 Apr 2025, 14:23
by jsantos
Hi Tomas,

Those macros are available if you compile Noesis from source. If you don’t, you’ll need to implement your own leak detection mechanism using the memory allocation callback. If you’re using standard malloc in Visual Studio, you can use _CrtDumpMemoryLeaks().

Let me know if this helps.

Re: Memory Leaks

Posted: 06 Apr 2025, 09:23
by Tomas
Hi Tomas,

Those macros are available if you compile Noesis from source. If you don’t, you’ll need to implement your own leak detection mechanism using the memory allocation callback. If you’re using standard malloc in Visual Studio, you can use _CrtDumpMemoryLeaks().

Let me know if this helps.
Hi,
The NoesisGui sources are not available and _CrtDumpMemoryLeaks() does not help either((

first, I need to remove the assertion that occurs on Fonts Release.
inside Noesis::Shutdown(), perhaps this is the reason for the leaks.
Screenshot 2025-04-06 100708.jpg
Screenshot 2025-04-06 104051.jpg
Screenshot 2025-04-06 104051.jpg (11.63 KiB) Viewed 4103 times
What reason could this assertion have?

Re: Memory Leaks

Posted: 07 Apr 2025, 19:51
by jsantos
Hi Tomas,

Could you please provide a bit more context regarding the license you're using? Is this an evaluation license? I’m asking because I noticed you're using the symbol server, because you are getting clean call stacks.

If that’s the case, and you reimplement memory allocation using malloc/free, you should be able to use _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF) at initialization and _CrtDumpMemoryLeaks() on exit to get a list of memory leaks, along with their allocation IDs. If you then set _crtBreakAlloc to one of those IDs, it should trigger a debugger break the next time you run the game, allowing you to catch the allocation in real time. This is explained in the MSDN. It will only work if the IDs are the same with every execution though.

As for the asserts you’re seeing, they appear to be related to XAML nodes with font families that aren’t being released properly. These unreleased nodes are likely leaving font references in the global font cache.

Let me know if you need help digging further into this.

Re: Memory Leaks

Posted: 07 Apr 2025, 20:54
by Tomas
Could you please provide a bit more context regarding the license you're using? Is this an evaluation license? I’m asking because I noticed you're using the symbol server, because you are getting clean call stacks.
I have an Indie license.
In the release build, only the size of the leak is printed in the log.
The call stack I provided is a debugging build + .pdb

Re: Memory Leaks

Posted: 08 Apr 2025, 16:54
by Tomas
The leak was due to binding to the parent element in xaml.
This leak was not diagnosed before version 3.2.7

Re: Memory Leaks

Posted: 08 Apr 2025, 20:02
by jsantos
Do you have a minimal XAML example that reproduces this? I'd love to take a closer look

Re: Memory Leaks

Posted: 08 Apr 2025, 22:17
by Tomas
Do you have a minimal XAML example that reproduces this? I'd love to take a closer look
<DataTemplate DataType="{x:Type RadioItem}">
	<IconRadioButton
		Margin="{Binding Margin}"
		CheckedIcon="{Binding Icon.Value}"
		FontFamily="{Binding Icon.Family}"
		Icon="{Binding Icon.Value}"
		IsChecked="{Binding IsChecked}"
		Style="{StaticResource Style.IconRadioButton.Toolbar}"
		Visibility="{Binding IsVisible, Converter={StaticResource Converter.Visibility}}">
		<IconRadioButton.GroupName>
			<MultiBinding Converter="{StaticResource Converter.GroupName}">
				<Binding Path="Group" />
           			<Binding RelativeSource="{RelativeSource AncestorType={x:Type ItemsControl}}" />
     			</MultiBinding>
		</IconRadioButton.GroupName>
	</IconRadioButton>
</DataTemplate>
One RadioItem component can be bound to multiple controls, so I created a converter that generates a unique group name for each control. Otherwise, IsChecked will always be false.
This is a brief explanation of why I had to implement it like that.

The following line leads to a memory leak:
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ItemsControl}}" />