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:内存管理的小秘密的主要内容,如果未能解决你的问题,请参考以下文章