VB6:内存管理的小秘密

Posted

技术标签:

【中文标题】VB6:内存管理的小秘密【英文标题】:VB6: Minor memory management mystery 【发布时间】:2017-06-30 15:43:52 【问题描述】:

我无法完全理解刚刚在 VB6 程序中发生的事情。这是在 Win7-64 和 Win10 上。

我为加载和显示 4K (3640x2160) 图像编写了一个问答概念证明。每张图片占用 24MB 内存,所以我“知道”,基于 32 位进程的 2GB 内存限制,我最多可以加载大约 80 张图片。

系统有 32GB 内存,但我的程序无法访问这些内存...对吗?

Const nPix As Long = 80

Dim Pix(1 To nPix) as stdPicture  ' an OLE construct
For k = 1 to nPix
   Pix(k) = LoadPicture("next in folder")
Next

没问题,需要一点时间,但可以正常工作并使用预期的内存。

对于笑声,我将 nPix 增加到 100,只是为了看看它是如何失败的。但它没有。尝试了 nPix = 200,然后是 300。仍然继续,然后吃掉了 8GB 的​​系统内存。完全没有问题:

PictureBox.PaintPicture Pix(300)

这到底是怎么回事?我在使用谁的内存,如何使用?

【问题讨论】:

这确实是独立的 VB6(而不是例如可以是 x64 的 VBA)?在进程管理器中,所有消耗的内存都归于VB进程吗?结果会不会改变你PaintPicture所有的循环? @GSerg - 是的,独立的本机代码编译的 VB6 应用程序。在 IDE 中也会发生同样的情况。进程管理器显示 8GB 正在使用中,其中 1.8GB 分配给 VB6 应用程序没有其他进程占用其余部分。我可以整天从数组中绘制随机图像,每个图像不到 1 毫秒,分配中没有显示任何变化。 显然这是virtual memory is not virtual address space 的一个例子。 Windows 尽可能多地映射内存(例如1.8GB),其余的在您尝试访问不同图片时按需映射/取消映射。如果Pix 数组必须自己存储图片位(因此必须同时映射所有图片),这将不起作用,但它每个只存储 4 个字节的指针,并且数据被映射到个人基础。 @GSerg - 当然,这是虚拟内存(所有 Windows 内存都是),但 VB6 不理解 > 2GB、虚拟或其他的地址空间,以及那些 4 字节指针(真的“处理”我猜测)显然不能指向其 2GB 分配之外。所以我想是 OLE 在 VB 背后处理这个问题。没有抱怨,这是一件很棒的事情,只是非常出乎意料(我)。 没有 32 位进程可以理解这样的地址。关键是虚拟寻址涉及多层地址解析表。 Pix 中的指针指向 2GB 内,但这些映射到的地址稍后如何解析是另一回事。这就是为什么“虚拟内存不是虚拟地址空间”。 【参考方案1】:

我认为这是因为图像是由操作系统本身加载的,并且只返回某种句柄给 VB6 进程进行操作......

【讨论】:

以上是关于VB6:内存管理的小秘密的主要内容,如果未能解决你的问题,请参考以下文章

写给Java开发的小程序布局指南,面试必会

源码解读·RT-Thread操作系统内存管理之内存池

深入理解JVM自动内存管理机制

19.1-uC/OS-III内存管理应用

string内存管理

Tensoflw.js - 02 - 模型与内存管理(易懂)