2015-06-07 3 views
4

Я пытаюсь использовать Json.net для сериализации и десериализации объектов в универсальном проекте Windows. Мне нужно использовать эту библиотеку в фоновом задании, и поскольку память для фоновых задач очень ограничена на телефоне Windows, мне нужно убедиться, что я не использую слишком много памяти.Использование памяти Json.net

Проблема, с которой я сталкиваюсь, заключается в том, что Json.net, похоже, использует много памяти, которая никогда, кажется, не освобождается.

Чтобы продемонстрировать это, я создал небольшой пример. Создание нового универсального приложения и создать PageLoaded обработчик события следующим образом (в данном примере это же в окнах приложений, как это в приложении телефона, так что не имеет значения, какую платформу вы используете):

private void Page_Loaded(object sender, RoutedEventArgs e) 
    { 
     List<string> testItems = new List<string>(); 
     List<string> destinationItems; 
     testItems.Add("Test Item Number 001"); 
     testItems.Add("Test Item Number 002"); 
     testItems.Add("Test Item Number 003"); 
     testItems.Add("Test Item Number 004"); 
     testItems.Add("Test Item Number 005"); 
     testItems.Add("Test Item Number 006"); 
     testItems.Add("Test Item Number 007"); 
     testItems.Add("Test Item Number 008"); 
     testItems.Add("Test Item Number 009"); 
     testItems.Add("Test Item Number 010"); 
     testItems.Add("Test Item Number 011"); 
     testItems.Add("Test Item Number 012"); 
     testItems.Add("Test Item Number 013"); 
     testItems.Add("Test Item Number 014"); 
     testItems.Add("Test Item Number 015"); 
     testItems.Add("Test Item Number 016"); 
     testItems.Add("Test Item Number 017"); 
     testItems.Add("Test Item Number 018"); 
     testItems.Add("Test Item Number 019"); 
     testItems.Add("Test Item Number 020"); 
     testItems.Add("Test Item Number 021"); 
     testItems.Add("Test Item Number 022"); 
     testItems.Add("Test Item Number 023"); 
     testItems.Add("Test Item Number 024"); 
     testItems.Add("Test Item Number 025"); 
     testItems.Add("Test Item Number 026"); 
     testItems.Add("Test Item Number 027"); 
     testItems.Add("Test Item Number 028"); 
     testItems.Add("Test Item Number 029"); 
     testItems.Add("Test Item Number 030"); 
     testItems.Add("Test Item Number 031"); 
     testItems.Add("Test Item Number 032"); 
     testItems.Add("Test Item Number 033"); 
     testItems.Add("Test Item Number 034"); 
     testItems.Add("Test Item Number 035"); 
     testItems.Add("Test Item Number 036"); 
     testItems.Add("Test Item Number 037"); 
     testItems.Add("Test Item Number 038"); 
     testItems.Add("Test Item Number 039"); 
     testItems.Add("Test Item Number 040"); 
     testItems.Add("Test Item Number 041"); 
     testItems.Add("Test Item Number 042"); 
     testItems.Add("Test Item Number 043"); 
     testItems.Add("Test Item Number 044"); 
     testItems.Add("Test Item Number 045"); 
     testItems.Add("Test Item Number 046"); 
     testItems.Add("Test Item Number 047"); 
     testItems.Add("Test Item Number 048"); 
     testItems.Add("Test Item Number 049"); 
     testItems.Add("Test Item Number 050"); 
     testItems.Add("Test Item Number 051"); 
     testItems.Add("Test Item Number 052"); 
     testItems.Add("Test Item Number 053"); 
     testItems.Add("Test Item Number 054"); 
     testItems.Add("Test Item Number 055"); 
     testItems.Add("Test Item Number 056"); 
     testItems.Add("Test Item Number 057"); 
     testItems.Add("Test Item Number 058"); 
     testItems.Add("Test Item Number 059"); 
     testItems.Add("Test Item Number 060"); 
     testItems.Add("Test Item Number 061"); 
     testItems.Add("Test Item Number 062"); 
     testItems.Add("Test Item Number 063"); 
     testItems.Add("Test Item Number 064"); 
     testItems.Add("Test Item Number 065"); 
     testItems.Add("Test Item Number 066"); 
     testItems.Add("Test Item Number 067"); 
     testItems.Add("Test Item Number 068"); 
     testItems.Add("Test Item Number 069"); 
     testItems.Add("Test Item Number 070"); 
     testItems.Add("Test Item Number 071"); 
     testItems.Add("Test Item Number 072"); 
     testItems.Add("Test Item Number 073"); 
     testItems.Add("Test Item Number 074"); 
     testItems.Add("Test Item Number 075"); 
     testItems.Add("Test Item Number 076"); 
     testItems.Add("Test Item Number 077"); 
     testItems.Add("Test Item Number 078"); 
     testItems.Add("Test Item Number 079"); 
     testItems.Add("Test Item Number 080"); 
     testItems.Add("Test Item Number 081"); 
     testItems.Add("Test Item Number 082"); 
     testItems.Add("Test Item Number 083"); 
     testItems.Add("Test Item Number 084"); 
     testItems.Add("Test Item Number 085"); 
     testItems.Add("Test Item Number 086"); 
     testItems.Add("Test Item Number 087"); 
     testItems.Add("Test Item Number 088"); 
     testItems.Add("Test Item Number 089"); 
     testItems.Add("Test Item Number 090"); 
     testItems.Add("Test Item Number 091"); 
     testItems.Add("Test Item Number 092"); 
     testItems.Add("Test Item Number 093"); 
     testItems.Add("Test Item Number 094"); 
     testItems.Add("Test Item Number 095"); 
     testItems.Add("Test Item Number 096"); 
     testItems.Add("Test Item Number 097"); 
     testItems.Add("Test Item Number 098"); 
     testItems.Add("Test Item Number 099"); 
     testItems.Add("Test Item Number 100"); 

     Debug.WriteLine(GC.GetTotalMemory(true)); 
     string saveStr = JsonConvert.SerializeObject(testItems); 
     Debug.WriteLine(GC.GetTotalMemory(true)); 
     destinationItems = JsonConvert.DeserializeObject<List<string>>(saveStr); 
     Debug.WriteLine(GC.GetTotalMemory(true)); 
     destinationItems = null; 
     Debug.WriteLine(GC.GetTotalMemory(true)); 
    } 

выход отладки:

Я ожидаю, что последнее значение приблизится к первому значению, но кажется, что Json.net занимает около 150 килобайт памяти. Более того, последующие инструкции по сериализации и десериализации, похоже, ухудшают ситуацию.

Я не пробовал это в приложении для рабочего стола Windows, но я ожидал бы, что результаты будут одинаковыми.

Мои вопросы: Кто-нибудь знает, почему это происходит и как освободить эту память? Если это невозможно, кто-нибудь знает другую библиотеку Json, которая лучше управляет памятью?

Редактировать: После битвы с этим в течение некоторого времени я понял, что проблема не в Json.net, а в потоках в WinRT.

Я задал новый вопрос на MSDN (в надежде, что кто-то в Microsoft могли бы объяснить) здесь: WinRT Stream Memory Issue

ответ

3

Насколько я знаю, нет никакой гарантии, что GC фактически возвращают все неиспользуемые объекты при вызове GC.GetTotalMemory (true). Вам нужно будет протестировать это в течение более длительного времени с большим количеством данных, чтобы быть уверенным в фактической утечке памяти.

Я вполне уверен, что кеши JSON.NET генерируют сериализаторы/десериализаторы по соображениям производительности, и они не будут восстановлены в этом сценарии. Однако фактический объем используемой памяти не должен увеличиваться при непрерывной сериализации/десериализации ранее сериализованных/десериализованных типов.

+0

В фоновой задаче WinRT я считаю, что было бы лучше ограничить использование памяти и снизить эффективность. – Slade

+0

В примере, который я привел, сохраняется только 100-символьная строка. Трудно обосновать 150 КБ памяти для ее сериализации. – Slade

Смежные вопросы