天天看點

簡單測試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的替代測試

簡單測試Newtonsoft.json JObject記憶體占用配置設定
簡單測試Newtonsoft.json JObject記憶體占用配置設定

2.使用Newtonsoft.json JObject測試

簡單測試Newtonsoft.json JObject記憶體占用配置設定
簡單測試Newtonsoft.json JObject記憶體占用配置設定

可以從圖中看到JProperty JValue JToken占用記憶體情況,而String,int,boolean屬于測試資料的記憶體配置設定

3.使用JsonTextWriter測試如下

簡單測試Newtonsoft.json JObject記憶體占用配置設定
簡單測試Newtonsoft.json JObject記憶體占用配置設定

以上測試隻截取部分圖例,更深層次讀者可以下載下傳源代碼自行調試觀看。

下載下傳源代碼

結語

JsonTextWriter和拼寫字元串差別不大,如果隻是把json以字元串形式傳回,盡量使用JsonTextWriter來處理,進而減少對象的生成。

JObject可以使用字典或者實體模型方式來代替,然後使用JsonConvert.SerializeObject 序列化。

轉載于:https://www.cnblogs.com/johnwu/archive/2013/02/19/2917286.html