VB6中的动态内存分配 [英] Dynamic memory allocation in VB6

查看:418
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆