You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内存中压缩JSON对象?14MB JSON加载占360MB内存求优化方案

优化JSON加载的内存占用问题

嘿,这个问题我太熟了——14MB的JSON加载成JObject居然占了360MB内存,这其实是Json.NET(Newtonsoft.Json)用动态JToken树的典型副作用,每个JObject/JProperty都带着一堆元数据,内存开销自然爆炸。给你几个实用的优化方向:

一、调整Json.NET的配置减少内存开销

你当前的代码用了默认的JsonSerializer配置,很多不必要的功能会额外占用内存,可以关闭这些选项:

  • 关闭类型名称处理:默认情况下Json.NET可能会保留类型信息(哪怕你没用到),添加这行:serializer.TypeNameHandling = TypeNameHandling.None;
  • 禁用日期自动解析:如果你的JSON里没有日期字符串,关闭日期解析能避免不必要的对象创建:serializer.DateParseHandling = DateParseHandling.None;
  • 使用JsonLoadSettings忽略冗余信息:加载JObject时传入配置,忽略注释和行信息,减少额外内存占用:
    JObject data = JObject.Load(red, new JsonLoadSettings {
        CommentHandling = CommentHandling.Ignore,
        LineInfoHandling = LineInfoHandling.Ignore
    });
    

二、替换为强类型模型(最有效!)

JObject是动态结构,每个属性都要存储额外的元数据(比如属性名、类型信息等),换成强类型类能直接砍掉这些冗余开销,内存占用会大幅下降。
首先根据你的JSON结构定义模型:

public class OrderValidationData
{
    public int Count { get; set; }
    public string Name { get; set; }
    public List<string> Keys { get; set; }
    public Dictionary<string, OrderDetail> Data { get; set; }
}

public class OrderDetail
{
    public decimal MinimalNetPrice { get; set; }
    public decimal VatRate { get; set; }
}

然后修改加载代码,直接反序列化到强类型模型:

public static void Load(string path = CacheFilePath) {
    path = Path.GetFullPath(path);
    if (!File.Exists(path)) return;
    JsonSerializer serializer = new JsonSerializer();
    using (FileStream s = File.Open(path, FileMode.Open))
    using (StreamReader sr = new StreamReader(s))
    using (JsonReader red = new JsonTextReader(sr)) {
        var validationData = serializer.Deserialize<OrderValidationData>(red);
        // 这里使用validationData即可
    }
}

这种方式的内存占用会接近JSON本身的大小(加上对象的基本开销),远低于360MB。

三、换用System.Text.Json(.NET Core/.NET 5+)

如果你用的是较新的.NET版本,微软官方的System.Text.Json在内存效率上比Json.NET的JObject更优,尤其是配合强类型模型使用:

public static void Load(string path = CacheFilePath) {
    path = Path.GetFullPath(path);
    if (!File.Exists(path)) return;
    var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
    using (FileStream s = File.Open(path, FileMode.Open)) {
        var validationData = JsonSerializer.Deserialize<OrderValidationData>(s, options);
        // 使用数据
    }
}

它的底层用Utf8处理,避免了额外的字符串转换,内存开销更小。

四、流式处理(如果不需要全量数据)

如果你的业务不需要把整个JSON都留在内存里,可以在读取时逐个处理条目,比如遍历Data里的每个订单详情,处理完就释放,不过看你的结构可能需要全量数据,这个作为备选方案。

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:24:14