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

Delphi 10.4.1环境下JSON操作代码出现内存泄漏求错误排查

Delphi 10.4 JSON代码内存泄漏问题排查结果

代码中存在的两个核心错误

  • 子JSON对象无异常保护导致泄漏
    你在oResultJO的try块内直接创建oSecondJO、oFirstJO两个对象,没有配套的异常处理逻辑。如果oSecondJO创建成功后,oFirstJO创建或后续代码抛出异常,已经创建的oSecondJO/oFirstJO没有释放逻辑,会直接泄漏。
  • 重复添加同名字段存在泄漏风险
    连续两次给oFirstJO添加TYPE_1字段:
    • 当TJSONObject.Duplicates为默认值dupAccept时,会保留两个同名字段,虽然不会直接泄漏,但不符合JSON标准,多数第三方JSON解析库只会读取最后一个同名字段的值,属于不规范写法。
    • 当TJSONObject.Duplicates设置为dupReplace时,添加第二个同名字段会直接覆盖旧字段,且旧的TJSONNumber(1)实例以及对应的TJSONPair不会被自动释放,直接造成内存泄漏。

修正后的代码示例

oResultJO := TJSONObject.Create;
try
  oSecondJO := nil;
  oFirstJO := nil;
  try
    oSecondJO := TJSONObject.Create;
    oFirstJO := TJSONObject.Create;

    // 先删除已存在的同名字段再添加,避免重复键问题
    var oOldPair := oFirstJO.RemovePair('TYPE_1');
    if Assigned(oOldPair) then
      oOldPair.Free;
    oFirstJO.AddPair('TYPE_1', TJSONNumber.Create(1));
    // 如确实需要保留重复键请注释上述删除逻辑,恢复第二条添加代码
    // oFirstJO.AddPair('TYPE_1', TJSONNumber.Create(2));

    oSecondJO.AddPair('TYPE_2', TJSONNumber.Create(3));

    if oFirstJO.Count > 0 then
    begin
      oResultJO.AddPair('FIRST', oFirstJO);
      oFirstJO := nil; // 交给父对象管理后置空,避免重复释放
    end;

    if oSecondJO.Count > 0 then
    begin
      oResultJO.AddPair('SECOND', oSecondJO);
      oSecondJO := nil; // 交给父对象管理后置空,避免重复释放
    end;

    ShowMessage(oResultJO.ToString);
  finally
    // 统一释放未交给父对象的资源
    oFirstJO.Free;
    oSecondJO.Free;
  end;
finally
  oResultJO.Free;
end;

修正逻辑说明

  • 给子对象创建逻辑增加独立的try-finally块,所有未交给父对象oResultJO的子对象统一在finally块释放,避免异常场景下的泄漏。
  • 添加同名字段前先调用RemovePair删除旧字段并手动释放,既符合JSON规范,也避免重复键场景下的泄漏。
  • 子对象交给父对象管理后立即将变量置空,避免后续重复释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 03:39:02