如何在 Delphi 中正确释放/最终化 ActiveX DLL?
我们在这里使用一个名为 ODNCServer 的类 - 在初始化时,会创建一个 TAutoObjectFactory
对象:
initialization
pAutoObjectFactory := TAutoObjectFactory.Create(ComServer, TODNCServer, Class_ODNCServer, ciSingleInstance, tmApartment);
现在 FastMM 抱怨内存泄漏,因为该对象没有在任何地方释放。如果我添加这样的终结语句,
finalization
if assigned(pAutoObjectFactory) then
TAutoObjectFactory(pAutoObjectFactory).Free;
那么该对象将被释放,但是之后会弹出有关内存泄漏的FastMM对话框,所以实际上,操作系统似乎正在卸载DLL,而不是程序。 ODNCServer 的实例是这样创建
fODNCServer := TODNCServer.Create(nil);
//register into ROT
OleCheck(
RegisterActiveObject(
fODNCServer.DefaultInterface, // instance
CLASS_ODNCServer, // class ID
ACTIVEOBJECT_STRONG, //strong registration flag
fODNCServerGlobalHandle //registration handle result
));
和释放的:
if ((assigned(fODNCServer)) and (fODNCServerGlobalHandle <> -1)) then
begin
Reserved := nil;
OleCheck(RevokeActiveObject(fODNCServerGlobalHandle,Reserved));
fDTRODNCServerGlobalHandle := -1;
end;
FreeAndNil(fODNCServer);
那么,有人知道我必须更改什么才能消除内存泄漏吗?顺便说一句,我也尝试过使用FastMM的RegisterExpectedMemoryLeaks来注册并忽略泄漏,但这似乎不起作用。此外,即使这只是一种解决方法,我想知道执行此操作的正确方法。
We are using a class called ODNCServer here - at initialization, an TAutoObjectFactory
object is created:
initialization
pAutoObjectFactory := TAutoObjectFactory.Create(ComServer, TODNCServer, Class_ODNCServer, ciSingleInstance, tmApartment);
Now FastMM is complaining about a memory leak because this object isn't freed anywhere. If I add a finalization statement like this
finalization
if assigned(pAutoObjectFactory) then
TAutoObjectFactory(pAutoObjectFactory).Free;
then the object is freed, but after the FastMM dialog about the memory leak pops up, so actually, the OS seems to be unloading the DLL, not the program. Instances of ODNCServer
are created like this
fODNCServer := TODNCServer.Create(nil);
//register into ROT
OleCheck(
RegisterActiveObject(
fODNCServer.DefaultInterface, // instance
CLASS_ODNCServer, // class ID
ACTIVEOBJECT_STRONG, //strong registration flag
fODNCServerGlobalHandle //registration handle result
));
and freed like this:
if ((assigned(fODNCServer)) and (fODNCServerGlobalHandle <> -1)) then
begin
Reserved := nil;
OleCheck(RevokeActiveObject(fODNCServerGlobalHandle,Reserved));
fDTRODNCServerGlobalHandle := -1;
end;
FreeAndNil(fODNCServer);
So, does anybody know what I have to change to get rid of that memory leak? By the way, I also tried using FastMM's RegisterExpectedMemoryLeaks
to register and ignore the leak, but this doesn't seem to work. Additionally, even if, it would just be a workaround and I'd like to know the right way to do this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
别担心。这并不是严格意义上的“泄露”。是的,您正在创建一个永远不会释放的对象,但关键字是“an”。单一的。
您的应用程序/DLL 不会“泄漏”内存,因为它会创建这些对象的大量实例,从而不断增加其内存使用量。此外,当进程终止时,该单个工厂对象(以及其他类似对象)使用的内存将被清除。
如果您显示了用于调用 RegisterExpectedMemoryLeak() 的代码,则可能可以确定为什么它无法处理您的特定情况。
Don't worry about it. It's not a "leak" in the strict sense. Yes you are creating an object that is never free'd, but the keyword is "an". Singular.
Your application/DLL will not "leak" memory in the sense that it will create numerous instances of these objects,continually increase it's memory use. Furthermore the memory used by that single factory object (and others like it) will be cleaned up when the process terminates anyway.
If you showed the code you are using to call RegisterExpectedMemoryLeak() it might be possible to determine why it is not working your specific case.