View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001671 | NoesisGUI | Unity | public | 2020-04-27 20:01 | 2020-05-07 20:09 |
| Reporter | rockhound | Assigned To | sfernandez | ||
| Priority | normal | Severity | major | ||
| Status | resolved | Resolution | fixed | ||
| Product Version | 2.2.6 | ||||
| Target Version | 3.0.0 | Fixed in Version | 3.0.0 | ||
| Summary | 0001671: Adding elements to a panel and removing them is not de-allocating memory | ||||
| Description | If we check ControlGallery's sample project it seems like memory allocated reported by NoesisSettings in Noesis' Unity Package is going up and down based on which elements are being displayed. Seems like a simple Child = null is enough to trigger the unloading of those resources. On the other hand in the example provided here, ControlGallery sample itself as well as the Inventory sample are being added to a Grid and later removed but reported memory allocated is not going down. | ||||
| Steps To Reproduce |
| ||||
| Attached Files | |||||
| Platform | Any | ||||
|
Some of the leaks come from event hooking, there is a known problem we described here: https://www.noesisengine.com/docs/3.0/Gui.Core.EventsTutorial.html#weak-events-in-c For the Inventory sample there are other issues I was not able to identify yet, we'll continue working on that. |
|
|
ControlGallery MainWindow.xaml code behind updated. MainWindow.xaml.cs (8,312 bytes)
#if UNITY_5_3_OR_NEWER
#define NOESIS
using Noesis;
using UnityEngine;
using Grid = Noesis.Grid;
#else
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media.Animation;
#endif
namespace ControlGallery
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : UserControl
{
public MainWindow()
{
System.WeakReference wr = new System.WeakReference(this);
KeyDown += (s, e) => { ((MainWindow)wr.Target).OnKeyDown(s, e); };
Initialized += (s, e) => { ((MainWindow)wr.Target).OnInitialized(s, e); };
InitializeComponent();
}
private void OnKeyDown(object sender, KeyEventArgs args)
{
NukeIt();
}
#if NOESIS
private void InitializeComponent()
{
Noesis.GUI.LoadComponent(this, "Assets/Resources/GUI/Samples/ControlGallery/MainWindow.xaml");
}
#endif
private void OnInitialized(object sender, EventArgs args)
{
System.WeakReference wr = new System.WeakReference(this);
SizeChanged += (s, e) => { ((MainWindow)wr.Target).OnSizeChanged(s, e); };
_styleSelector = (ComboBox)FindName("StyleSelector");
_styleSelector.SelectionChanged += (s, e) => { ((MainWindow)wr.Target).OnStyleSelectionChanged(s, e); };
_noesisStyleResources = (ResourceDictionary)LoadXaml("NoesisStyle");
_simpleStyleResources = (ResourceDictionary)LoadXaml("SimpleStyle");
_windowsStyleResources = (ResourceDictionary)LoadXaml("WindowsStyle");
_selector = (Grid)FindName("Selector");
_sampleSelector = (TreeView)FindName("SampleSelector");
_sampleSelector.SelectedItemChanged += (s, e) => { ((MainWindow)wr.Target).OnSamplesSelectionChanged(s, e); };
_sampleContainer = (Viewbox)FindName("SampleContainer");
_sampleContainer1 = (Border)FindName("SampleContainer1");
_sampleContainer2 = (Border)FindName("SampleContainer2");
_sampleContainer.Resources = _noesisStyleResources;
_sampleOverlay = (Grid)FindName("SampleOverlay");
_sampleOverlay.MouseDown += (s, e) => { ((MainWindow)wr.Target).OnSampleOverlayMouseDown(s, e); };
_showContainer1 = (Storyboard)Resources["ShowContainer1"];
_showContainer2 = (Storyboard)Resources["ShowContainer2"];
_selectorTopContainer = (Border)FindName("SelectorTopContainer");
_selectorTop = (StackPanel)FindName("SelectorTop");
_selectorTopExpand = (ToggleButton)FindName("SelectorTopExpand");
_selectorLeftContainer = (Border)FindName("SelectorLeftContainer");
_selectorLeft = (StackPanel)FindName("SelectorLeft");
_selectorLeftExpand = (ToggleButton)FindName("SelectorLeftExpand");
_itemHeight = (Decorator)FindName("ItemHeight");
}
void OnStyleSelectionChanged(object sender, SelectionChangedEventArgs args)
{
switch (_styleSelector.SelectedIndex)
{
case 0:
_sampleContainer.Resources = _noesisStyleResources;
break;
case 1:
_sampleContainer.Resources = _simpleStyleResources;
break;
case 2:
_sampleContainer.Resources = _windowsStyleResources;
break;
}
args.Handled = true;
}
void OnSamplesSelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> args)
{
object newValue = args.NewValue;
TreeViewItem tvi = (TreeViewItem)newValue;
if (tvi != null && !tvi.HasItems)
{
string sampleName = (string)tvi.Tag;
if (_lastSample != sampleName)
{
LoadSample(sampleName);
_lastSample = sampleName;
}
}
}
void LoadSample(string sampleName)
{
_sampleSelector.IsEnabled = false;
UIElement sample = (UIElement)LoadXaml(sampleName);
if (_sampleContainer1.Child == null)
{
// Show container 1
_sampleContainer1.Child = sample;
_showContainer1.Completed += OnShowSampleCompleted;
_showContainer1.Begin();
}
else
{
// Show container 2
_sampleContainer2.Child = sample;
_showContainer2.Completed += OnShowSampleCompleted;
_showContainer2.Begin();
}
}
object LoadXaml(string xaml)
{
#if NOESIS
return Noesis.GUI.LoadXaml("Assets/Resources/GUI/Samples/ControlGallery/Data/" + xaml + ".xaml");
#else
string path = "/Assets/NoesisGUI/Samples/ControlGallery/Data/" + xaml + ".xaml";
return Application.LoadComponent(new Uri(path, UriKind.Relative));
#endif
}
void OnShowSampleCompleted(object sender, EventArgs e)
{
if (_sampleContainer1.Visibility == Visibility.Visible)
{
// Container 1 shown
_showContainer1.Completed -= OnShowSampleCompleted;
_sampleContainer2.Child = null;
}
else
{
// Container 2 shown
_showContainer2.Completed -= OnShowSampleCompleted;
_sampleContainer1.Child = null;
}
_sampleSelector.IsEnabled = true;
}
void NukeIt()
{
_selectorTopContainer.Child = null;
_selectorLeftContainer.Child = null;
_sampleContainer1.Child = null;
_sampleContainer2.Child = null;
_lastSample = null;
}
void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
Size newSize = e.NewSize;
if (newSize.Width > newSize.Height)
{
// Landscape
_selectorTopContainer.Child = null;
_selectorLeftContainer.Child = _selector;
_selectorTop.Visibility = Visibility.Collapsed;
_selectorLeft.Visibility = Visibility.Visible;
_selectorTopExpand.IsChecked = false;
_itemHeight.Height = newSize.Width * 0.05f;
}
else
{
// Portrait
_selectorLeftContainer.Child = null;
_selectorTopContainer.Child = _selector;
_selectorLeft.Visibility = Visibility.Collapsed;
_selectorTop.Visibility = Visibility.Visible;
_selectorLeftExpand.IsChecked = false;
_itemHeight.Height = newSize.Height * 0.05f;
}
}
void OnSampleOverlayMouseDown(object sender, MouseButtonEventArgs e)
{
_selectorLeftExpand.IsChecked = false;
_selectorTopExpand.IsChecked = false;
}
#region Private members
ComboBox _styleSelector;
ResourceDictionary _noesisStyleResources;
ResourceDictionary _simpleStyleResources;
ResourceDictionary _windowsStyleResources;
Grid _selector;
TreeView _sampleSelector;
string _lastSample;
Viewbox _sampleContainer;
Border _sampleContainer1;
Border _sampleContainer2;
Grid _sampleOverlay;
Storyboard _showContainer1;
Storyboard _showContainer2;
Border _selectorTopContainer;
StackPanel _selectorTop;
ToggleButton _selectorTopExpand;
Border _selectorLeftContainer;
StackPanel _selectorLeft;
ToggleButton _selectorLeftExpand;
Decorator _itemHeight;
#endregion
}
}
|
|
|
After more investigation I found interactivity classes are also producing memory leaks. |
|
|
Thanks sfernandez. Was about to post reporting that replacing event hooks with WeakReferences didn't show any improvements in our project's memory usage. We are looking forward for your next release. |
|
|
Already fixed in our repository, will be available tomorrow in RC5 |
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2020-04-27 20:01 | rockhound | New Issue | |
| 2020-04-27 20:01 | rockhound | Tag Attached: C# | |
| 2020-04-27 20:01 | rockhound | Tag Attached: Memory | |
| 2020-04-27 20:01 | rockhound | Tag Attached: Unity | |
| 2020-04-27 23:55 | rockhound | Steps to Reproduce Updated | |
| 2020-04-28 10:38 | sfernandez | Assigned To | => sfernandez |
| 2020-04-28 10:38 | sfernandez | Status | new => assigned |
| 2020-04-28 10:38 | sfernandez | Target Version | => 3.0.0 |
| 2020-04-28 13:39 | rockhound | Steps to Reproduce Updated | |
| 2020-05-01 15:42 | sfernandez | Status | assigned => feedback |
| 2020-05-01 15:42 | sfernandez | Note Added: 0006306 | |
| 2020-05-01 15:43 | sfernandez | File Added: MainWindow.xaml.cs | |
| 2020-05-01 15:43 | sfernandez | Note Added: 0006307 | |
| 2020-05-05 00:52 | sfernandez | Note Added: 0006318 | |
| 2020-05-05 18:35 | rockhound | Note Added: 0006321 | |
| 2020-05-05 18:35 | rockhound | Status | feedback => assigned |
| 2020-05-05 18:39 | rockhound | Note Edited: 0006321 | |
| 2020-05-05 21:23 | jsantos | Note Added: 0006322 | |
| 2020-05-07 20:09 | sfernandez | Status | assigned => resolved |
| 2020-05-07 20:09 | sfernandez | Resolution | open => fixed |
| 2020-05-07 20:09 | sfernandez | Fixed in Version | => 3.0.0 |
| 2025-10-10 13:29 | jsantos | Category | Unity3D => Unity |