Json.net内存使用情况

时间:2015-06-07 15:27:59

标签: c# json.net win-universal-app

我正在尝试使用Json.net来序列化和反序列化Windows通用项目中的对象。我需要在后台任务中使用这个库,并且因为后台任务的内存在Windows手机上非常有限,我需要确保我没有使用太多内存。

我遇到的问题是Json.net似乎使用了大量内存,似乎永远不会被释放。

为了证明这一点,我创建了一个小例子。创建一个新的通用应用程序并创建一个PageLoaded事件处理程序,如下所示(此示例在Windows应用程序中与在手机应用程序中相同,因此您使用哪个平台无关紧要):

    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));
    }

调试输出为:

40236

193084

199624

193472

我希望最后一个值与第一个值大致匹配,但似乎Json.net保留了大约150kb的内存。更重要的是,后续的序列化和反序列化指令似乎使情况变得更糟。

我没有在Windows桌面应用中试过这个,但我希望结果是一样的。

我的问题是: 有谁知道为什么会这样,以及如何释放这段记忆? 如果这是不可能的,有没有人知道另一个更好地管理内存的Json库?

编辑:经过一段时间的斗争,我意识到问题不是Json.net,而是WinRT中的流问题。

我在MSDN上提出了一个新问题(希望微软的某个人可以解释一下): WinRT Stream Memory Issue

1 个答案:

答案 0 :(得分:3)

据我所知,当您调用GC.GetTotalMemory(true)时,无法保证GC实际上已经回收了所有未使用的对象。您需要使用更多数据对此进行更长时间的测试,以确保存在实际的内存泄漏。

我很确定JSON.NET会出于性能原因缓存生成的序列化器/反序列化器,并且在这种情况下不会回收它们。但是,在先前序列化/反序列化类型的连续序列化/反序列化期间,实际使用的内存量不应增加。