.NET Form close / dispose не освобождает глобальные объекты - PullRequest
0 голосов
/ 26 июня 2018

Редактировать: Пожалуйста, примите во внимание образец, который я предоставил. Там нет событий, которые называются. Код, который я предоставил, - это все, что есть. Я просто хочу знать, глобальные объекты в форме должны быть вручную выделены. Было бы неплохо также узнать, почему форма, выходящая из области видимости, не очищается, но это вторично.

Закрытие или вызов dispose в форме, похоже, не освобождает глобальные объекты этой формы. У меня есть форма, которая будет создаваться несколько раз, и после открытия несколько раз я получаю исключение OutOfMemory, даже если все предыдущие формы были закрыты. Я могу освободить память, сделав каждый объект, который я использую, одноразовым, но я думал, что в целом сборка мусора позаботилась о том, чтобы вычистить объекты из области видимости.

Вот простой пример формы с многомерным двойным массивом:

using System;
using System.Windows.Forms;

namespace surGroupTool
{
    public partial class TestForm : Form
    {
        double[,] testArray;

        public TestForm()
        {
            InitializeComponent();

            testArray = new double[5000, 5000];
        }

    }
}

Когда я создаю форму в бесконечном цикле, ей быстро не хватает памяти, даже если я удаляю ее и устанавливаю в ноль.

while (true)
{
    TestForm testForm = new TestForm();

    testForm.Dispose();
    testForm = null;
} 

Должен ли каждый объект быть утилизирован вручную для закрытой / утилизированной формы?

enter image description here

1 Ответ

0 голосов
/ 26 июня 2018

enter image description here

Мне не удалось воспроизвести проблему с указанным исходным кодом. Этот скриншот от около 20 секунд. Но я оставил его включенным во время приготовления кофе, и все было в порядке Это было зацикливание шаблона памяти, как показано выше.

Одна вещь, которую я заметил, состоит в том, что требуется некоторое время, прежде чем GC освобождает память. GC запускается только тогда, когда вы начинаете испытывать недостаток памяти или когда вызываете его вручную с помощью GC.Collect();. В этот момент запускается фоновый процесс, который выполняет фактическую очистку. Этот поток сборки мусора не полностью прерывает основной поток ваших программ (согласно документации Microsoft > фоновая сборка мусора рабочей станции). Таким образом, это означает, что можно продолжать выделять память даже во время работы GC. На этом этапе это гонка, которая является первой. Вы выделяете достаточно памяти, чтобы выйти за пределы. или ваш GC с его очисткой.

Должен ли каждый объект быть утилизирован вручную для закрытой / утилизированной формы?

Нет, обычно глобальные ресурсы не должны выбрасываться. GC очистит их, если ничто не ссылается на них. Однако, если глобальные ресурсы - это неуправляемые ресурсы (например, stream или bitmap), вам необходимо утилизировать их, прежде чем их можно будет очистить, то же самое относится и к локальным неуправляемым ресурсам.

из комментариев:

Это происходит, даже если каждая форма создается пользователем, нажимающим кнопку ... с минутами между создаваемыми формами.

Я собираюсь предположить, что это в вашем реальном приложении, а не в форме, предоставленной в качестве тестового образца. Скорее всего, вы оставляете ссылку на эту форму (например, через результат диалога или открываете неповрежденный ресурс). Если это с данной формой, я не могу объяснить это, и вам, возможно, придется проверить, не перезаписали ли вы настройки GC чем-то очень экзотическим или все вместе отключили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...