Excel VBA - 填充Variant数组增加内存使用量
我是新来的,如果我的问题已经被回答,提前抱歉,但我现在搜索了几天,发现没有解决方案或解释呢。Excel VBA - 填充Variant数组增加内存使用量
问题是,在一个变种阵列的人口中,内存消耗不断增加。该阵列的尺寸是,并且当它是第一个尺寸时,我可以看到内存消耗如何增加相应的量。我认为,一小块的代码将更好地解释它比文字:
Sub test()
Dim Arr(1 To 1000000, 1 To 10) As Variant
Dim i As Long, j As Integer
For i = 1 To 1000000
For j = 1 To 10
Arr(i, j) = "AAAAAAAAA"
Next j
Next i
End Sub
我这段代码的经验是 - 阵列标注内存利弊之后。增加约。 160 MB(即10 * 1 000 000 * 16)。执行完成后,我已经增加了大约400 MB!有趣的是 - 如果用一个数字替换字符串AAAA,这个问题就消失了。
在实际的程序(这只是一个测试代码)我有一个更大的数组约。 600 MB,但在代码执行结束时,内存使用量为3.4 GB!结果是“内存不足”错误。
任何人都可以解释一下吗?
由于提前, 书斋
你们看到的是,当一个变种包含字符串,实际的字符串数据没有在内部存储的事实引起的。一个变体由16个字节组成。这16个字节的布局描述如下here。请注意,这些字节中的8个包含类型信息之类的内容,其他8个包含实际数据,该数据为数字。当数据是字符串时,这8个字节是不够的。相反,这8个字节包含一个指向BSTR结构的指针,该结构由4个字节组成,其中包含一个字符串长度,字符串中的实际字符(每个字符2个字节)和一个2个字符的空终止符。对于长度为9的字符串,可以计算出24个字节,因此总共需要16 + 24 = 40个字节来存储该字符串(以及它指向的变体)。这就解释了为什么当你以这种方式存储这1000万个字符串时,至少需要400 MB的空间。
正如你所看到的,变种是一个记忆猪。如果你真的需要使用Excel VBA来做这件事,你应该避免像鼠疫这样的变种阵列。字符串本身效率不高。也许你可以做一些事情,比如将字符的ascii代码存储为字节,或者将许多字符串合并成一个可以在需要时拆分的字符串。
John,非常感谢您提供了一个简单明了的解释!它现在有很多意义。我基本上知道变体是不好的,效率低下的,但我不知道它们太糟糕了。我的数据实际上主要是数字,它只包含数据列的标题。在这种情况下使用变体只是比较简单,其中一个原因是我通过将文本文件读为二进制数据来获取数据,以便获取一个字符串,并将其分割并写入变体数组。但是,由于它造成了问题,我想我将不得不使用一个小的字符串数组作为标题和一个单独的双数组作为数据。 – Den
为什么你觉得奇怪的是,当你把一个数组中的字符串,用来存储该数组的内存增加?字符串本身不存储在变量变量的内存中。无论如何,Excel VBA可能是这种规模数据的错误工具。也许使用像R这样的东西(如果你想保留某个前端,可以与Excel进行交互)可能是一个很好的战略举措。 –
以下内容可能会帮助您理解为什么使用大型变体阵列来存储大量字符串会使用如此多的内存:http://bytecomb.com/vba-internals-whats-in-a-variable/ –
我很善良必须为这项任务而努力。我没有预料到内存消耗会增长,因为我声明了这个数组,所以我期待它会保留必要的内存,这是16字节,用于不同时间的列时间行,在这种情况下是160 MB,我可以在声明数组时,请参阅任务管理器中的+160 MB。但是在执行期间,内存使用量会增加,直到我有另外的400 Mb,那么对于那个数组大小,总共660 Mb?当为阵列填充双打时,为什么内存消耗不会增加?我看到了提议的主题,但我会阅读的链接,谢谢。 – Den