簡單測試Newtonsoft.json JObject內存占用分配


前言

最近在優化一個項目,發現使用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 序列化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM