• VLMI - форум по обмену информацией. На форуме можете найти способы заработка, разнообразную информацию по интернет-безопасности, обмен знаниями, курсы/сливы.

    После регистрации будут доступны основные разделы.

    Контент форума создают пользователи, администрация за действия пользователей не несёт ответственности, отказ от ответственности. Так же перед использованием форума необходимо ознакомиться с правилами ресурса. Продолжая использовать ресурс вы соглашаетесь с правилами.
  • Подпишись на наш канал в Telegram для информации о актуальных зеркалах форума: https://t.me/vlmiclub

Как освободить память при закрытии формы WPF

TesterProger

Новичок
Сообщения
5
Реакции
0
0 руб.
Суть проблемы заключается в том, что при закрытие формы память приложения не освобождается, это в свою очередь порождает утечку памяти.

Ниже представлен примитивный пример данной проблемы.
XML:
<Window x:Class="TreeView.EntryPoint"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TreeView"
        mc:Ignorable="d"
        Title="EntryPoint" Height="450" Width="800">
    <Grid>
        
    </Grid>
</Window>

C#:
using System.Windows;

namespace TreeView
{
    // Основная форма в которой происходит открытие другой формы
    public partial class EntryPoint : Window
    {

        public EntryPoint()
        {
            InitializeComponent();


            MainWindow form = new MainWindow();
            form.Show();

        }
    }
}
XML:
<Window x:Class="TreeView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TreeView"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" Closed="Window_Closed">
    <Grid>
        <!--Оптимизация и хеширование для TreeView отключены, сделано это для показания маштаба утечки -->
        <TreeView x:Name="treeView1"  Background="#FF303030" />

    </Grid>
</Window>

C#:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;


namespace TreeView
{
    // Форма в которой не происходит уничтожение обьектов после закрытия
    public partial class MainWindow : Window
    {
        Random rand = new Random();

        /// <summary>
        /// Создание рандомной строки
        /// </summary>
        /// <returns></returns>
        string GetRandString()
        {
            StringBuilder src = new StringBuilder();

            for (int i = 0; i < 10; i++)
                src.Append((char)rand.Next(0, 255));

            return src.ToString();
        }

        public MainWindow()
        {
            InitializeComponent(); // Инициализация и создание объектов

            // Эмулирование логики формы
            //-----------------------------------------------------
            List<string> list = new List<string>(); // Список строк

            for (int i = 0; i < 10500; i++)
                list.Add(GetRandString());  // Заполнение списка

            foreach (var n in list)
                treeView1.Items.Add(n); // Добавляет новую ветку в TreeView
            //-----------------------------------------------------
        }

        private void Window_Closed(object sender, EventArgs e)
        {
          
        }
    }
}

Методы решения проблемы:
Данный метод не даст результат
C#:
 GC.Collect();
 GC.WaitForPendingFinalizers();
Данный метод не даст результат
C#:
  [DllImportAttribute("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern int SetProcessWorkingSetSize(IntPtr process, int minimumWorkingSetSize, int maximumWorkingSetSize);

        public static void FlushMemory()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
            }
        }

В реальности есть приложение которое принимает данные и асинхронно отображает их в новом потоке в виде формы, после закрытия формы, возникает проблема проблема описанная выше.

Есть ли решение данной проблемы?
C#:
Environment.Exit(0);
 

ZeroByte

Senior Developer

ZeroByte

Senior Developer
Местный
Сообщения
82
Реакции
325
0 руб.
Please note, if you want to make a deal with this user, that it is blocked.
Магия хогвартса
23738
23739
 

TesterProger

Новичок
Сообщения
5
Реакции
0
0 руб.
Ну и каким образом ты очистил память? По сути он заполняет TreeView, следовательно все его значения подвешены в памяти.

XML:
<Window x:Class="TreeView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TreeView"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  Closed="Window_Closed">
    <Grid x:Name="MainGrid">
        <!--Оптимизация и хеширование для TreeView отключены, сделано это для показания маштаба утечки -->
        <TreeView x:Name="treeView1"  Background="#FF303030" />

    </Grid>
</Window>

C#:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;


namespace TreeView
{
    // Форма в которой не происходит уничтожение обьектов после закрытия
    public partial class MainWindow : Window
    {
        Random rand = new Random();

        /// <summary>
        /// Создание рандомной строки
        /// </summary>
        /// <returns></returns>
        string GetRandString()
        {
            StringBuilder src = new StringBuilder();

            for (int i = 0; i < 10; i++)
                src.Append((char)rand.Next(0, 255));

            return src.ToString();
        }

        public MainWindow()
        {
            InitializeComponent(); // Иницилизация и создание обьектов

            // Эмулирование логики формы
            //-----------------------------------------------------
            List<string> list = new List<string>(); // Список строк

            for (int i = 0; i < 10500; i++)
                list.Add(GetRandString());  // Заполнение списка

            foreach (var n in list)
                treeView1.Items.Add(n); // Добавляет новую ветку в TreeView
                                        // -----------------------------------------------------
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            treeView1.Items.Clear(); // Очищаю TreeView но это не помогает
            this.MainGrid.Children.Remove(treeView1);

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
    }
}

Эта попытка очистки снижает с 221мб до 179мб, но память все равно растет..
 
Сверху Снизу