vb6 - VB6 中的动态内存分配

标签 vb6 memory-management

有这样的事吗?

我说的是类似于 C++ new 命令的东西,即需要显式释放内存(或有内存泄漏风险)的内存分配。

我问是因为我记得以前必须通过将表单/控件/其他对象设置为 Nothing 来解决一些 GDI 泄漏问题,但现在不记得是什么或为什么...

在 VB6 中开发时,我们是否需要担心内存管理?

最佳答案

就 VB6 中的内存管理而言,有几个方面值得关注。

第一种是循环引用,子类指向父类,反之亦然。如果没有明确设置对 Nothing 的引用,这有时适用于表单,尤其是作为 Target 对象编辑器的对话框。再次确保将所有内容设置为空即可解决问题。

基本原则是 1) 如果一个对象指向的任何东西都是“活着的”,那么它就不会被垃圾回收。因此,当您设置对循环引用的父对象的引用时,子对象还活着,因此父对象不会被垃圾收集,因为父对象还活着,所以子对象不会被垃圾收集。

与表单相同。如果您没有将编辑对象的对话框的目标属性设置为空,那么只要目标对象处于事件状态,它就不会触发最后一系列事件。

这样做最常见的副作用是您的应用程序无法正常关闭,并且您的内存占用会随着应用程序使用时间的延长而增加。

至于 GDI 泄漏,只要您使用使用句柄、指针的外部 DLL。对于这些功能,您将自己置于与 C++ 相同的领域。因此,您必须确保遵守所使用的特定 API 或 DLL 的所有规则,这些规则通常涉及在用完后显式销毁您创建的内容。

循环引用问题有一个优雅的解决方案。您使用代理而不是子直接引用父。

首先为父对象制作一个Proxy Class。

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

然后在Parent中定义一个私有(private)变量

Private WithEvents MyProxy As MyObjectProxy

Private Sub Class_Initialize()
    Set MyProxy = New MyObjectProxy
End Sub

然后设置一个名为 Proxy 的只读属性并实现 GetRef 事件。

Public Property Get Proxy() As MyObjectProxy
    Set Proxy = MyProxy
End Property

Private Sub MyProxy_GetRef(RHS As MyObject)
    Set RHS = Me
End Sub

对于 child 或其他任何需要引用的代码如下。

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 程序员的祸根。

注意:我从中得到的消息称它为代理,但感谢 Anthony 的评论,我发现它也符合调解器模式的定义。它使用特定的 VB6 Centric 功能;事件 API,它不完全符合中介者模式的精神。

还意识到 .NET 框架具有与 VB6 的事件 API 等效的功能,尽管它的实现方式不同(委托(delegate)等)

关于vb6 - VB6 中的动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/264541/

相关文章:

VB6 将文本框输入限制为从 1900 年到当前日期范围内的数字?

multithreading - 在vb6编程中使用线程

c++ - c++ 中 vector<T> 中的内存管理

c++ vector of vectors 销毁

objective-c - Dealloc 未被调用

objective-c - 为什么我不应该在 init 方法中使用访问器方法

c - 如何从 vb6 调用 native C DLL

ms-access - VB6 Ms Access 数据库编辑大量记录

events - 阻止 TreeView 在 VB6 中触发事件?

java - 使用 Windows 的 NetBeans 中忽略的最大内存大小