GVKun编程网logo

简单测试Newtonsoft.json JObject内存占用分配(newtonsoft.json 内存溢出)

19

本文将分享简单测试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 内存溢出)

简单测试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 使用 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 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移除属性,在序列化时忽略

原文 C# Newtonsoft.Json JObject移除属性,在序列化时忽略

一、针对 单个 对象移除属性,序列化时忽略处理

JObject实例的 Remove() 方法,可以在 指定序列化时移除属性和值

示例如下 :

[csharp]  view plain  copy
  1. //json 序列化  
  2. JObject obj1 = JObject.FromObject(new  
  3. {  
  4.     id = 1,  
  5.     name = "张三",  
  6.     age = 20  
  7. });  
  8. Console.WriteLine(obj1.ToString());  
  9. //输出:  
  10. //{  
  11. //  "id": 1,  
  12. //  "name": "张三",  
  13. //  "age": 20  
  14. //}  
  15.   
  16.   
  17. //指定忽略对象的属性  
  18. //注:指定的key区分大小写  
  19. obj1.Remove("id");  
  20. Console.WriteLine(obj1.ToString());  
  21. //输出结果:  
  22. //{  
  23. //    "name": "张三",  
  24. //    "age": 20  
  25. //}  

注 :1.属性移除仅对当前 对象的属性起作用

2.指定移除 的 key区分 大小写,移除的属性需要和属性 大小写一直

如想 删除二级数组对象的属性,可以参考 代码:

[csharp]  view plain  copy
  1. JArray jarr = obj1.SelectToken("images") as JArray;  
  2. if (jarr != null)  
  3.     foreach (JObject item in jarr)  
  4.     {  
  5.         item.Remove("id");  
  6.     }  

 

 

二、使用 [Newtonsoft.Json.JsonIgnore()]   ,属性标注用于忽略处理

[csharp]  view plain  copy
  1. [Newtonsoft.Json.JsonIgnore()]  
  2. 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 在双引号前添加反斜杠

如何解决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 在双引号前添加反斜杠等相关内容,可以在本站寻找。

本文标签: