我试图使用Json.net在windows通用项目中序列化和反序列化对象。我需要在后台任务中使用这个库,因为windows phone的后台任务内存非常有限,我需要确保我没有使用太多的内存。
我遇到的问题是,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流内存问题
据我所知,当您调用GC. gettotalmemory (true)时,不能保证GC实际上已经回收了所有未使用的对象。您将需要用更多的数据进行更长时间的测试,以确保确实存在内存泄漏。
我很确定JSON。. NET缓存出于性能原因生成的序列化器/反序列化器,在此场景中不会回收它们。但是,在对先前序列化/反序列化的类型进行连续序列化/反序列化期间,实际使用的内存量不应该增加。