本文将分享简单测试Newtonsoft.jsonJObject内存占用分配的详细内容,并且还将对newtonsoft.json内存溢出进行详尽解释,此外,我们还将为大家带来关于.net使用Newton
本文将分享简单测试Newtonsoft.json JObject内存占用分配的详细内容,并且还将对newtonsoft.json 内存溢出进行详尽解释,此外,我们还将为大家带来关于.net 使用 Newtonsoft.Json 输出树状 json字符串、asp.net core 3.0 JObject The collection type ''Newtonsoft.Json.Linq.JObject'' is not supported、C# Newtonsoft.Json JObject移除属性,在序列化时忽略、C# Newtonsoft.Json.JsonConvert.SerializeObject 在双引号前添加反斜杠的相关知识,希望对你有所帮助。
本文目录一览:- 简单测试Newtonsoft.json JObject内存占用分配(newtonsoft.json 内存溢出)
- .net 使用 Newtonsoft.Json 输出树状 json字符串
- asp.net core 3.0 JObject The collection type ''Newtonsoft.Json.Linq.JObject'' is not supported
- C# Newtonsoft.Json JObject移除属性,在序列化时忽略
- C# Newtonsoft.Json.JsonConvert.SerializeObject 在双引号前添加反斜杠
简单测试Newtonsoft.json JObject内存占用分配(newtonsoft.json 内存溢出)
http://www.th7.cn/Program/net/201302/125491.shtml
前言
最近在优化一个项目,发现使用asp.net api时候发现内存占用过高。从中发现有某处地方直接使用Newtonsoft.json 的JArray对象序列化后返回HttpResponseMessage,
也有一部分是直接返回JArray,后来怀疑JObject内存占用过高,此函数是使用队列来生成报表文件数据量比较大,而传输方式使用Json,解析为了方便而直接使用JArray.Parse,
改为反序列化IList<IDictionary<string,object>>后有所改观;经笔者测试发觉JObject产生的对象确实对内存占用过多而无法准确释放。
测试
Release测试1W条数据每行30列
一、NewtonsoftTest
string guid = Guid.NewGuid().ToString();JArray array = new JArray();for (int i=0; i < 10000; i++) { JObject obj = new JObject(); for (int c=1; c <= 10; c++) { obj["Id_" + c] = i; obj["Guid_" + c] = guid; obj["Sex_" + c] = i % 2 == 0; } array.Add(obj);}
进程内存占用80M左右
二、FCLCollectionTest
string guid = Guid.NewGuid().ToString();IList<IDictionary<string,object>> array = new List<IDictionary<string,object>>();for (int i=0; i < 10000; i++) { var obj = new Dictionary<string,object>(); for (int c=1; c <= 10; c++) { obj["Id_" + c] = i; obj["Guid_" + c] = guid; obj["Sex_" + c] = i % 2 == 0; } array.Add(obj);}
进程内存占用28M左右
三、JsonWriterTest
string guid = Guid.NewGuid().ToString();var jsonWriter = new JsonTextWriter(new StringWriter(CultureInfo.InvariantCulture));jsonWriter.Formatting = Formatting.None;jsonWriter.WriteStartArray();for (int i=0; i < 10000; i++) { jsonWriter.WriteStartObject(); for (int c=1; c <= 10; c++) { jsonWriter.WritePropertyName("Id_" + c); jsonWriter.WriteValue(i); jsonWriter.WritePropertyName("Guid_" + c); jsonWriter.WriteValue(guid); jsonWriter.WritePropertyName("Sex_" + c); jsonWriter.WriteValue(i % 2 == 0); } jsonWriter.WriteEndobject();}jsonWriter.WriteEndarray();
进程内存占用24M左右
分析
因笔者时间不多,只做了部分测试,使用CLRProfiler来分析程序的内存分配
1.使用Dictionary<string,object>来作为JObject的替代测试
2.使用Newtonsoft.json JObject测试
可以从图中看到JProperty JValue JToken占用内存情况,而String,int,boolean属于测试数据的内存分配
3.使用JsonTextWriter测试如下
以上测试只截取部分图例,更深层次读者可以下载源代码自行调试观看。
下载源代码
结语
JsonTextWriter和拼写字符串区别不大,如果只是把json以字符串形式返回,尽量使用JsonTextWriter来处理,从而减少对象的生成。
JObject可以使用字典或者实体模型方式来代替,然后使用JsonConvert.SerializeObject 序列化。
.net 使用 Newtonsoft.Json 输出树状 json字符串
测试环境:.net FrameWork 4.0
操作系统:window Server 2008 R2
Newtonsoft.Json 下载地址:http://json.codeplex.com/
1、解压缩下载文件夹:Json50r8
2、引入Json50r8/Bin 下的 相对应.net版本的dll文件 到项目中
执行以下代码:
using System; using System.Collections.Generic; using Newtonsoft.Json; public partial class _Default : System.Web.UI.Page { private string jsonString = @"[ { 'id': '1','text': '电脑整机','parentid': '0','children': [ { 'id': '2','text': '笔记本','parentid': '1','children': [ { 'id': '31','text': 'SONY','parentid': '2','children': [] },{ 'id': '23','text': 'LENOVO',{ 'id': '25','text': 'IBM',{ 'id': '26','text': '宏基',{ 'id': '27','text': '联想',{ 'id': '28','text': '联想2','children': [] } ] },{ 'id': '3','text': '上网本',{ 'id': '4','text': '平板电脑',{ 'id': '5','text': '台式机',{ 'id': '6','text': '服务器','children': [] } ] },{ 'id': '7','text': '电脑配件','children': [ { 'id': '8','text': 'cpu','parentid': '7',{ 'id': '9','text': '主板',{ 'id': '10','text': '显卡',{ 'id': '11','text': '硬盘',{ 'id': '12','text': '内存',{ 'id': '13','text': '机箱',{ 'id': '14','text': '电源',{ 'id': '15','text': '显示器',{ 'id': '16','text': '刻录机/光驱',{ 'id': '17','text': '声卡',{ 'id': '18','text': '扩展卡','children': [] } ] },{ 'id': '32','text': '手机','children': [ { 'id': '33','text': '诺基亚','parentid': '32','children': [ { 'id': '34','text': '华为','children': [] } ] },{ 'id': '34','text': '三星','text': '小米','text': '苹果','children': [] } ] },'text': '篮球','parentId': '1','children': [] } ];"; protected void Page_Load(object sender,EventArgs e) { treeNode rootNode = new treeNode(); rootNode.id="1"; rootNode.text="电脑整机"; rootNode.parentid="0"; treeNode childNode1 = new treeNode(); childNode1.id="2"; childNode1.text="笔记本"; childNode1.parentid="1"; treeNode childNode2 = new treeNode(); childNode2.id="3"; childNode2.text="SONY"; childNode2.parentid="1"; if (rootNode.children == null) rootNode.children = new List<treeNode>(); rootNode.children.Add(childNode1); rootNode.children.Add(childNode2); string json = JsonConvert.SerializeObject(rootNode,Formatting.Indented); } /// <summary> /// 树结构(根据js插件定义的数据结构) /// </summary> public class treeNode { private string _id; private string _text; private string _parentid; private List<treeNode> _children; public string id { get { return _id; } set { _id = value; } } public string text { get { return _text; } set { _text = value; } } public string parentid { get { return _parentid; } set { _parentid = value; } } public List<treeNode> children { get { return _children; } set { _children = value; } } } }
asp.net core 3.0 JObject The collection type ''Newtonsoft.Json.Linq.JObject'' is not supported
在asp.net core 3.0 中,如果直接在Controller
中返回 Jobject
类型,会抛出如下错误:
The collection type ''Newtonsoft.Json.Linq.JObject'' is not supported.
System.NotSupportedException: The collection type ''Newtonsoft.Json.Linq.JObject'' is not supported.
at System.Text.Json.JsonPropertyInfoNotNullable`4.GetDictionaryKeyAndValueFromGenericDictionary(WriteStackFrame& writeStackFrame, String& key, Object& value)
at System.Text.Json.JsonPropertyInfo.GetDictionaryKeyAndValue(WriteStackFrame& writeStackFrame, String& key, Object& value)
at System.Text.Json.JsonSerializer.HandleDictionary(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
该问题的出现估计与.net 3.0 新引入的System.Text.Json
类库有关.
折衷的解决办法是:
使用Content
方法将 JObject
类型的返回值转为 ContentResult
类型.
伪代码如下:
[HttpPost]
public ContentResult Method1([FromBody]Param param1)
{
JObject result=xxx;
return Content(result.ToString());
}
如果有时间,建议跟一下System.Text.Json
类库的源码来彻底解决该问题.
C# Newtonsoft.Json JObject移除属性,在序列化时忽略
原文 C# Newtonsoft.Json JObject移除属性,在序列化时忽略
一、针对 单个 对象移除属性,序列化时忽略处理
JObject实例的 Remove() 方法,可以在 指定序列化时移除属性和值
示例如下 :
- //json 序列化
- JObject obj1 = JObject.FromObject(new
- {
- id = 1,
- name = "张三",
- age = 20
- });
- Console.WriteLine(obj1.ToString());
- //输出:
- //{
- // "id": 1,
- // "name": "张三",
- // "age": 20
- //}
- //指定忽略对象的属性
- //注:指定的key区分大小写
- obj1.Remove("id");
- Console.WriteLine(obj1.ToString());
- //输出结果:
- //{
- // "name": "张三",
- // "age": 20
- //}
注 :1.属性移除仅对当前 对象的属性起作用
2.指定移除 的 key区分 大小写,移除的属性需要和属性 大小写一直
如想 删除二级数组对象的属性,可以参考 代码:
- JArray jarr = obj1.SelectToken("images") as JArray;
- if (jarr != null)
- foreach (JObject item in jarr)
- {
- item.Remove("id");
- }
二、使用 [Newtonsoft.Json.JsonIgnore()] ,属性标注用于忽略处理
- [Newtonsoft.Json.JsonIgnore()]
- public int ID { get; set; }
更多:
C# Newtonsoft.Json JObject合并对象整理
C# dynamic类型序列化和反序列化之Newtonsoft.Json
C# Newtonsoft.Json JsonSerializerSettings配置序列化操作
C# Newtonsoft.Json.JsonConvert.SerializeObject 在双引号前添加反斜杠
如何解决C# Newtonsoft.Json.JsonConvert.SerializeObject 在双引号前添加反斜杠?
我有一个使用此代码返回 json 的 aspnet web api:
Project_Model mdl = new Project_Model(transactionId,data);
string json = string.Empty;
json = JsonConvert.SerializeObject(mdl);
这是变量“json”的值:
{\"Pj_Id\":\"23a6bd47-c35a-4ee3-8998-bd0406bc5839\",\"Pj_CUsr_Id\":\"8cb52c3e-25b7-412d-8010-cadd75f1f64b\",\"Pj_Number\":\"test 101\",\"Pj_Name\":\"Test Project 101\",\"Pj_Location\":\"1551 Main St,Houston\"}
但它应该是这样的:
{
"Pj_Id": "23a6bd47-c35a-4ee3-8998-bd0406bc5839","Pj_CUsr_Id": "8cb52c3e-25b7-412d-8010-cadd75f1f64b","Pj_Number": "test 101","Pj_Name": "Test Project 101","Pj_Location": "1551 Main St,Houston"
}
我知道我们会在调试器中得到这样的转义字符,但不会在输出中得到。上面带有反斜杠的示例是从 PostMan 相同 API 的输出中复制的。
谁能告诉我为什么会发生这种情况以及可以做些什么来清理它?
谢谢。
解决方法
@phuzi 在上面的评论中是正确的:
理想情况下,您不应该自己序列化 JSON,因为它很可能被双重序列化。只需从 ASP.Net Web API 操作方法而不是 JSON 返回 mdl
我对它进行了双重序列化。我刚刚返回了类,结果是完美的 json。
谢谢。
关于简单测试Newtonsoft.json JObject内存占用分配和newtonsoft.json 内存溢出的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于.net 使用 Newtonsoft.Json 输出树状 json字符串、asp.net core 3.0 JObject The collection type ''Newtonsoft.Json.Linq.JObject'' is not supported、C# Newtonsoft.Json JObject移除属性,在序列化时忽略、C# Newtonsoft.Json.JsonConvert.SerializeObject 在双引号前添加反斜杠等相关内容,可以在本站寻找。
本文标签: