KeldorKatarn
Topic Author
Posts: 239
Joined: 30 May 2014, 10:26

Help with avoiding memory allocations

28 Jan 2025, 21:43

Hi, I need some help in the hope to get rid of some memory allocations, if possible.
I see some happening here during measure and arrange and I'm not sure what's causing them:
Allocations.jpg
Might be related to this custom panel (just there to overlay things and meant to be more lightweight than Grid)
    /// <summary>A panel that stacks all its children on top of each other, letting them overlay each other.</summary>
    public class OverlayStackPanel : Panel
    {
        public OverlayStackPanel()
        {
            Loaded += OnLoaded;
        }

#if UNITY_5_3_OR_NEWER
        private List<UIElement> InternalChildren { get; set; } = null;
#endif

        /// <inheritdoc/>
        protected override Size MeasureOverride(Size availableSize)
        {
            if (InternalChildren is null)
            {
                return new Size(0, 0);
            }

            double maxWidth = 0;
            double maxHeight = 0;

            for (var index = 0; index < InternalChildren.Count; index++)
            {
                var child = InternalChildren[index];
                child?.Measure(availableSize);

                if (child is null)
                {
                    continue;
                }

                var childDesiredSize = child.DesiredSize;
                maxWidth = Math.Max(maxWidth, childDesiredSize.Width);
                maxHeight = Math.Max(maxHeight, childDesiredSize.Height);
            }

            // Panel size matches the largest child's size
            return new Size((float)maxWidth, (float)maxHeight);
        }

        /// <inheritdoc/>
        protected override Size ArrangeOverride(Size finalSize)
        {
            if (InternalChildren is null)
            {
                return finalSize;
            }

            // Arrange each child to occupy the same space (stacked on top of each other)
            for (var index = 0; index < InternalChildren.Count; index++)
            {
                var child = InternalChildren[index];

                // Positioning each child at (0, 0) ensures they are stacked on top of each other
                child?.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
            }

            return finalSize;
        }

        private void OnLoaded(object sender, RoutedEventArgs args)
        {
#if UNITY_5_3_OR_NEWER
	    // Cache children since calling Children in a loop seems to allocate
            InternalChildren = Children.ToList();
#endif
            Loaded -= OnLoaded;
        }
    }
Also I see some more allocations here related to PropertyChanged. Is this a boxing issue?
Allocations2.jpg
I have a notifying property of type Bracket, which is a Struct containing a Point, a Size and a bool.
Am I seeing these GetPropertyValue allocations because the structs get boxed? Can I avoid that somehow?
Also, I'm guessing feeding a Value Type into a IValueConverter will also always lead to boxing? For WPF it's fine but I'd love to avoid them in Unity if at all possible.

Also what's the Dictionary being used here?
Allocations1.jpg
 
User avatar
jsantos
Site Admin
Posts: 4264
Joined: 20 Jan 2012, 17:18
Contact:

Re: Help with avoiding memory allocations

05 Feb 2025, 19:06

We haven't forgotten about this post. However, the analysis requires time, and the team is quite busy preparing the first beta for Studio.

We will get back to this very soon.
 
KeldorKatarn
Topic Author
Posts: 239
Joined: 30 May 2014, 10:26

Re: Help with avoiding memory allocations

05 Feb 2025, 20:01

I found out by now that caching the children in OnLoaded caused a bug. But that's besides the point. I still couldn't tell where all those allocations came from. For now it's not a major issue I'm still in pre-production. But I'd like to hunt those down eventually.
 
User avatar
jsantos
Site Admin
Posts: 4264
Joined: 20 Jan 2012, 17:18
Contact:

Re: Help with avoiding memory allocations

18 Feb 2025, 18:15

Could you please create a ticket for this?
 
KeldorKatarn
Topic Author
Posts: 239
Joined: 30 May 2014, 10:26

Re: Help with avoiding memory allocations

18 Feb 2025, 19:11

Could you please create a ticket for this?
It's mainly this issue: https://www.noesisengine.com/bugs/view.php?id=3970

The boxing with value converters is a bit of a pain. There's no way to support generic Value converters I assume because that breaks compatibility with WPF?
 
User avatar
sfernandez
Site Admin
Posts: 3222
Joined: 22 Dec 2011, 19:20

Re: Help with avoiding memory allocations

19 Feb 2025, 12:10

What do you mean by generic value converters?
The Binding only allows to assign an IValueConverter, which has an API that works with object values for input and output. I don't think there is much we can do about it without breaking user code.
 
KeldorKatarn
Topic Author
Posts: 239
Joined: 30 May 2014, 10:26

Re: Help with avoiding memory allocations

01 Mar 2025, 21:18

What do you mean by generic value converters?
The Binding only allows to assign an IValueConverter, which has an API that works with object values for input and output. I don't think there is much we can do about it without breaking user code.
I'm aware. unfortunately one of the bad legacy design remnants of WPF before generics were widely used to avoid boxing.
I've since moved a lot of code that used value converters into specialized controls. Triggering value conversion every frame is isn't a good option.
 
User avatar
jsantos
Site Admin
Posts: 4264
Joined: 20 Jan 2012, 17:18
Contact:

Re: Help with avoiding memory allocations

04 Mar 2025, 13:06

Even with generics (which I’m not sure how they would be used in XAML), boxing is still needed, or at least, I don’t currently see a way to avoid it.

In C++, we pool boxed values, making the process quite fast without significant extra memory allocation. Shouldn't C# be doing something similar? Have you measured the cost of boxing on your platform?

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot], Semrush [Bot] and 3 guests