下图显示了以下代码引入的内存泄漏:
方法:
procedure TInformationSource.SetConfig;
var
vJSONConfigList : TStringList;
vCurrentFileName : string;
vDebugString : string;
begin
if iCJSONByteStream = nil then
iCJSONByteStream := TBytesStream.Create;
if vJSONConfigList = nil then
vJSONConfigList := TStringList.Create;
for vCurrentFileName in uCInformationSourceConfigFileNames do
begin
iCJSONBytes := TFile.ReadAllBytes(vCurrentFileName);
iCJSONAsStr := TFile.ReadAllText(vCurrentFileName);
fMain.jdInformationSource.JsonText := iCJSONAsStr;
fMain.jtvInformationSource.LoadJson(false);
if iCConfigsList = nil then
iCConfigsList := TStringList.Create;
if iCJSONData = nil then
iCJSONData := TJSONArray.Create; // TJSONObject.Create();
iCJSONConfigData := TJSONObject.ParseJSONValue(iCJSONBytes , 0) as TJSONObject;
vDebugString := iCJSONConfigData.ToString;
iCEndpoint := GetActiveEndpoint;
iCHeaderParams := GetActiveHeaderParams;
iCActiveAuthParams := GetActiveAuthParams;
iCActiveProtocolParams := GetActiveProtocolParams;
iCActiveSourceName := GetActiveSourceName;
end;end;
对象的解构者:
destructor TInformationSource.Destroy;
begin
FreeandNil(iCHeaderParams); // Okay
FreeandNil(iCActiveProtocolParams); // Okay
FreeandNil(iCJSONByteStream); // Okay
FreeandNil(iCConfigsList); // Okay
FreeandNil(uCInformationSourceConfigFileNames); //Okay
//FreeandNil(iCJSONConfigData); // nil pointer access violation - Why?
//FreeandNil(iCActiveAuthParams); // nil pointer access violation - Why?
//FreeandNil(iCJSONData); // nil pointer access violation because TJSONArray Virtual base class?
//FreeandNil(iCAuthPairs); // nil pointer access violation because TJSONArray Virtual base class?
inherited;
end;
声明:
//...
private
iCJSONData : TJSONArray;
iCAuthPairs : TJSONArray;
iCHeaderParams : TJSONObject;
iCActiveAuthParams : TJSONArray;
iCActiveProtocolParams : TJSONObject;
iCActiveSourceName : String;
iCJSONAsStr : string;
iCJSONBytes : TBytes;
iCJSONByteStream : TBytesStream;
iCConfigsList : TStringList;
iCJSONConfigData : TJSONObject;
//...
现在,析构函数中的最后5个FreeandNil语句都会传递访问冲突。对于TJSONArray实例,我此时的理解是要么你不能FreeandNil TJSONArray对象因为你不能用.Create构造它们(编译器抱怨你已经用虚方法从类中实例化了一个对象) - 或者你如果使用TJSONValue.GetValue实例化它们,则只能FreeandNil。但是我不确定这是否属实,如果是,我不确定为什么会有这种差异。见下一段。
TJONValue是一个密封且因此无法扩展的类TJSONArray和TJSONObject的虚拟基类。我通过调用TJSONObject.ParseJSONValue和TJSONValue.GetValue来创建后一个对象的实例,其中X是要返回的值的类型(TJSONArray,TJSONObject)。
现在看起来我在通过调用TObject(TJSONObject.ParseJSONValue(...,TByteArray))创建的TJSONObject实例上获取FreeandNil的访问冲突(返回有效值),而我没有获得访问冲突通过调用TJSONValue.GetValue(keystring)创建的TJSONObjects;
我不明白为什么会这样。
TMoveArray泄漏是否与泄漏的TJSONArray对象相关联?
另外一个问题是 - 如何释放与TBytes实例关联的内存,这些内存是类型约束为字节类型的泛型TArray的实例?图像中的一些内存泄漏也与那些内存泄漏相关联。或者这是自动完成的,因此不会对下面的内存泄漏列表做出贡献。