Освобождение памяти связанной коллекции в приложении WPF MVVM - PullRequest
0 голосов
/ 26 января 2012

Прежде всего, читая различные посты на эту тему, я знаю, что освобождение памяти в мире .Net является своего рода запретной темой, и что в ней есть много недопонятых моментов и множество дискуссий.В любом случае, я чувствую, что не видел ответа, касающегося моей конкретной проблемы.И вот так.

Я работаю над приложением WPF "TCP logger", используя MVVM Light Toolkit, чтобы "внедрить" мою View-модель в DataContext View.Одним из элементов управления в представлении является TextBox «Log», который с помощью конвертера привязывается к ObservableCollection «LogEntries».Эта комбинация TextBox / ObservableCollection может быть заполнена тысячами элементов, потому что мое приложение может работать в течение нескольких дней без закрытия.

Чтобы проиллюстрировать то, что я до сих пор объяснял, вот что мы любим больше всего, код:

<Window ... DataContext="{Binding Source={StaticResource Locator}, 
                                  Path=PortListenerVM}"...>

<TextBox IsReadOnly="True">
    <TextBox.Text>
        <MultiBinding Converter="{x:Static l:Converters.LogEntryCollectionToTextConverter}">
            <Binding Path="LogEntries" Mode="OneWay"/>
            <Binding Path="UseTimeStamp"/>
            <Binding Path="LogEntries.Count" Mode="OneWay" />
        </MultiBinding>
    </TextBox.Text>
</TextBox>

А в виртуальной машине:

// The MVVM Light Toolkit part
public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<PortListenerViewModel>();
    }

    public PortListenerViewModel PortListenerVM
    {
        get
        {
            PortListenerViewModel portListenerVM = 
                ServiceLocator.Current.GetInstance<PortListenerViewModel>();
            return portListenerVM;
        }
    }
}    

// The damned collection which hogs memory
public ObservableCollection<LogEntry> LogEntries { get; set; }

// The command which should work wonders by releasing memory
public void ClearLog()
{
    this.SelectedListenerFromObject.LogEntries.Clear();
    this.SelectedListenerFromObject.HasTooManyLogEntries = false;
}
* 1010И поэтому, как и любой оптимист, я ожидал, что метод Clear освободит необходимую память, как только сборщик мусора выполнит свою работу.Нету.И «обнуление» Коллекции и форсирование GC.Collect также ничего не сделали.Впоследствии я узнал, что это ничего не дает, если что-то еще имеет ссылку на Коллекцию.

Теперь я перехожу к сути моего вопроса.Во-первых, как я могу узнать, кто хранит ссылку на коллекцию LogEntries?Во-вторых, может ли DataContext представления быть виновником, и если да, то как я смогу выпустить ссылки, которые он имеет на коллекцию (помня, что я использую ViewModelLocator из набора инструментов)?

Вторая часть дляМой вопрос был бы таков: поскольку диспетчер задач, по-видимому, не сообщает о точном использовании памяти, каков будет лучший способ оценить, сколько памяти потребляет мое приложение?Я использую Системный обозреватель , который показывает разные цифры в качестве диспетчера задач, но стоит ли им доверять?

1 Ответ

1 голос
/ 26 января 2012

Возможно, проблемы нет.GC очень ленив, и диспетчер задач показывает выделенную память, которая отличается от того, что GC фактически использует.ГХ может иметь объекты в одноразовом списке, но пока просто не видит в этом смысла.

Напишите себе тест на загрузку 100 000 предметов и очистку коллекции.Оставь это на ночь.

...