是的,它确实。
Json.NET在其
IContractResolver类
DefaultContractResolver和中缓存类型序列化信息
CamelCasePropertyNamesContractResolver。除非您指定自定义合同解析器,否则此信息将被缓存和重用。
对于
DefaultContractResolver全局静态实例,只要应用程序未指定其自己的合同解析器,Json.NET就会在内部维护该实例。
CamelCasePropertyNamesContractResolver另一方面,维护所有实例之间共享的静态表。(我认为不一致是由遗留问题引起的;有关详细信息,请参见此处。)
这两种类型均设计为完全线程安全的,因此线程之间的共享应该不是问题。
如果选择实现和实例化自己的合同解析器,则仅当您缓存和重用合同解析器实例本身时,类型信息才会被缓存和重用。因此,Newtonsoft
建议:
为了提高性能,您应该一次创建合同解析器,并在可能的情况下重用实例。解决合同的速度很慢,并且IContractResolver的实现通常会缓存合同。
如果存在内存消耗问题,
并且出于任何原因需要最大限度地减少缓存的合同永久占用的内存,则可以构造自己的本地实例
DefaultContractResolver(或某些自定义子类),使用该实例进行序列化,然后立即删除对其的所有引用,例如:
public class JsonExtensions{ public static string SerializeObjectNoCache<T>(T obj, JsonSerializerSettings settings = null) { settings = settings ?? new JsonSerializerSettings(); bool reset = (settings.ContractResolver == null); if (reset) // To reduce memory footprint, do not cache contract information in the global contract resolver. settings.ContractResolver = new DefaultContractResolver(); try { return JsonConvert.SerializeObject(obj, settings); } finally { if (reset) settings.ContractResolver = null; } }}如果您使用
CamelCasePropertyNamesContractResolver,请使用
DefaultContractResolver适当的命名策略切换至,例如:
settings.ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() };大部分缓存的协定内存( 但不是全部 )最终将被垃圾回收。当然,这样做 会严重影响序列化性能
。(某些表包含有关
enum类型和数据协定属性的反映信息,这些表在全球范围内共享,因此不会被回收。)
有关更多信息,
请参阅Newtonsoft的性能提示:重用合同解析器。



