VB6中的动态内存分配 [英] Dynamic memory allocation in VB6
问题描述
有这样的事情吗?
我说的是类似C ++ new
命令的东西,即分配内存,这需要显式释放内存(否则可能会导致内存泄漏).
I'm talking about something like a C++ new
command i.e. allocation of memory which necessitates explicit releasing of the memory (or risk memory leaks).
我之所以问,是因为我记得以前必须通过将窗体/控件/其他对象设置为Nothing
来解决一些GDI泄漏问题,但现在不记得是什么或为什么...
I ask because I remember having to solve some GDI leak problems previously by setting forms/controls/other objects to Nothing
but can't remember what or why now...
在VB6中进行开发时,我们是否需要担心内存管理?
Do we ever have to worry about memory management when developing in VB6?
推荐答案
VB6中的内存管理涉及多个方面.
There are several areas of concern as far as Memory management in VB6.
第一个是循环引用,子类指向父类,反之亦然.在没有显式设置对Nothing的引用的情况下,有时对于窗体也是如此,尤其是作为Target对象的编辑器的对话框.再次确保所有设置为空都可以解决问题.
The first are circular references where a child class points back to a parent and vice versa. Without explicitly setting the reference to Nothing, This is sometimes true of forms as well especially a dialog that is an editor for a Target object. Again making sure everything set to nothing will solve the problem.
基本原理是:1)如果对象所指向的任何东西都是活着的",则不会被垃圾收集.因此,当您将引用设置为循环引用的父对象时,子对象仍处于活动状态,因此父对象不会被垃圾收集,因为父对象仍处于活动状态,因此子对象不会被垃圾收集.
The fundamental principles are 1) If anything pointed to by an object is "alive" then it won't be garbage collected. So when you set the reference to the parent object of a circular reference the child is alive so the parent doesn't get garbage collected, since the parent still alive the child doesn't get garbage collected.
与表格相同.如果您未设置对话框的目标属性",则只要目标对象还活着,对其进行编辑就不会触发最终的一系列事件.
The same with forms. If you don't set the Target Property of a dialog that editing an object to nothing than it won't fire the final series of events as long as the Target Object is alive.
执行此操作最常见的副作用是您的应用程序无法正常关闭,并且使用该应用程序的时间越长,内存占用量就会越大.
The most common side effects of doing this are that your application won't shut down properly and your memory footprint will grow the longer the application is used.
对于GDI泄漏,只要您使用使用句柄,指针的外部DLL,就可以.对于这些功能,您将自己置于与C ++相同的领域.因此,必须确保遵循所使用的特定API或DLL的所有规则,这些规则通常涉及在完成使用后显式销毁所创建的内容.
As for GDI leaks, anytime you use an external DLL that uses handles, pointers. You put yourself in the same realm as C++ for those functions. So you have to make sure that you follow all the rules of the particular API or DLLs you are using which often involves explicitly destroying that which you created after you are done with it.
有一个很好的解决循环参考问题的方法.代替孩子直接引用父母,您可以使用代理.
There is an elegant solution for the circular reference problem. Instead of the child referencing a parent directly you use a proxy.
首先为父对象创建一个代理类.
First make a Proxy Class for the parent object.
Option Explicit Public Event GetRef(ByRef RHS As MyObject)
Public Function GetMyObject() As MyObject
Dim Ref As MyObject
RaiseEvent GetRef(Ref)
Set GetMyObject = Ref
End Function
然后在父级中定义一个私有变量
Then define a private variable in the Parent
Private WithEvents MyProxy As MyObjectProxy
Private Sub Class_Initialize()
Set MyProxy = New MyObjectProxy
End Sub
然后设置一个名为Proxy的只读属性并实现GetRef事件.
Then setup a read only property called Proxy and implement the GetRef event.
Public Property Get Proxy() As MyObjectProxy
Set Proxy = MyProxy
End Property
Private Sub MyProxy_GetRef(RHS As MyObject)
Set RHS = Me
End Sub
对于孩子或需要参考的其他任何东西,代码如下.
For the child or anything else that needs a reference the code is as follows.
Private ParentProxy As MyObjectProxy
Public Property Get Parent() As MyObject
If ParentProxy Is Nothing Then
Set Parent = Nothing
Else
Set Parent = ParentProxy.GetRef
End If
End Property
Public Property Set Parent(RHS As MyObject)
If RHS Is Me Then
Set MyObjectProxy = Nothing
ElseIf Target Is Nothing Then
Set MyObjectProxy = Nothing
Else
Set MyObjectProxy = RHS.Proxy
End If
End Property
由于事件机制不会在任何一个对象上设置引用或增加COM引用计数,因此可以避免整个循环引用问题,而这正是许多VB6程序员的祸根.
Because the event mechanism doesn't set references or increments the COM reference count on either object it avoids the whole circular reference problem that is the bane of many VB6 programmers.
注意:我从它那里获得的来源称为代理,但是由于安东尼的评论,我发现它也符合中介者模式的定义.它使用特定的VB6 Centric功能.事件API,这不完全符合Mediator模式的精神.
Note: The source I got it from called it a Proxy but thanks to Anthony's comment I find it also fits the definition of the Mediator Pattern. It uses a specific VB6 Centric feature; the Event API which isn't quite in the spirit of the Mediator Pattern.
也意识到.NET框架与VB6的Event API等效,尽管其实现方式不同(代理等)
Also realize that the .NET framework has equivalents to VB6's Event API although it is implemented differently (delegates, etc)
这篇关于VB6中的动态内存分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!