使用 SetLength() 调整引用计数接口动态数组的大小会导致内存泄漏吗?
Can resizing dynamic array of reference-counted interfaces with SetLength() cause memory leak?
如果我有以下引用计数接口的类型声明。
type
ISomeInterface = interface
['{xxxx-xxxx-xxx-xxxx-xxx}']
procedure doThing();
end;
TSomeInterfaceImpl = class(TInterfacedObject, ISomeInterface)
public
procedure doThing();
end;
...
var arrayOfSomeInterface : array of ISomeInterface;
下面的代码会不会导致内存泄漏?
SetLength(arrayOfSomeInterface, 1);
arrayOfSomeInterface[0] := TSomeInterfaceImpl.create();
SetLength(arrayOfSomeInterface, 2);
arrayOfSomeInterface[1] := TSomeInterfaceImpl.create();
据我所知,当在动态数组上调用 SetLength() 时,它会为新的动态数组分配新的内存,然后将旧的数组内容复制到新的数组中。
旧数组中接口的引用计数发生了什么变化。会适当递减吗?
没有,没有泄漏。
内存管理器将尝试就地扩展现有内存块。如果可以,则不会影响任何引用。但是,如果不能,它会将数组复制到一个新的内存块。生成的接口引用将具有与复制之前相同的引用计数。增加数组的大小不会添加或删除现有数组元素的引用,只会将它们从一个内存位置移动到另一个内存位置。这是绝对安全的。
接口和动态数组都是托管类型,编译器和RTL会正确管理它们。
如果我有以下引用计数接口的类型声明。
type
ISomeInterface = interface
['{xxxx-xxxx-xxx-xxxx-xxx}']
procedure doThing();
end;
TSomeInterfaceImpl = class(TInterfacedObject, ISomeInterface)
public
procedure doThing();
end;
...
var arrayOfSomeInterface : array of ISomeInterface;
下面的代码会不会导致内存泄漏?
SetLength(arrayOfSomeInterface, 1);
arrayOfSomeInterface[0] := TSomeInterfaceImpl.create();
SetLength(arrayOfSomeInterface, 2);
arrayOfSomeInterface[1] := TSomeInterfaceImpl.create();
据我所知,当在动态数组上调用 SetLength() 时,它会为新的动态数组分配新的内存,然后将旧的数组内容复制到新的数组中。
旧数组中接口的引用计数发生了什么变化。会适当递减吗?
没有,没有泄漏。
内存管理器将尝试就地扩展现有内存块。如果可以,则不会影响任何引用。但是,如果不能,它会将数组复制到一个新的内存块。生成的接口引用将具有与复制之前相同的引用计数。增加数组的大小不会添加或删除现有数组元素的引用,只会将它们从一个内存位置移动到另一个内存位置。这是绝对安全的。
接口和动态数组都是托管类型,编译器和RTL会正确管理它们。