如何在VB.NET中编程获取Object变量的内存占用量
VB.NET中统计DataReader填充数组的内存占用
针对你遇到的问题,下面提供几种可行的解决方案:
1. 用GC线程分配字节差统计(最简便准确)
GC.GetAllocatedBytesForCurrentThread可以获取当前线程已分配的托管内存总量,通过填充前后的差值,就能得到本次数组及所有元素占用的新增内存:
' 填充前记录内存值 Dim beforeAlloc As Long = GC.GetAllocatedBytesForCurrentThread() ' 执行填充操作 dr.GetValues(values) ' 计算本次内存占用 Dim memoryUsed As Long = GC.GetAllocatedBytesForCurrentThread() - beforeAlloc
这个方法会自动统计数组本身、值类型元素的内存,以及引用类型元素(如字符串)的实例内存,结果准确且无需额外处理类型逻辑。
2. 手动遍历元素计算内存(细粒度控制)
如果需要更精准的粒度(比如只统计数组本身和直接引用的大小),可以手动遍历数组元素,根据类型计算总内存:
Private Function GetArrayMemoryUsage(arr As Object()) As Long If arr Is Nothing Then Return 0 ' 托管数组的固定开销:64位系统24字节,32位系统12字节 Dim arrayBaseOverhead As Long = If(IntPtr.Size = 8, 24, 12) Dim totalElementMemory As Long = 0 For Each elem In arr If elem Is Nothing Then ' 空引用占用1个指针大小的内存 totalElementMemory += IntPtr.Size Continue For End If Dim elemType As Type = elem.GetType() If elemType.IsValueType Then ' 值类型直接取非托管大小(和托管大小一致) totalElementMemory += Marshal.SizeOf(elemType) Else If elemType Is GetType(String) Then ' 字符串内存:对象固定开销24字节 + 每个字符2字节(Unicode) Dim str = DirectCast(elem, String) totalElementMemory += 24 + str.Length * 2 Else ' 其他引用类型:先统计引用本身的指针大小 totalElementMemory += IntPtr.Size ' 若需统计引用对象的实例内存,可通过反射遍历字段计算,或使用Runtime内部API(注意兼容性) End If End If Next Return arrayBaseOverhead + totalElementMemory End Function
调用时直接传入values数组即可得到计算结果,缺点是需要处理多种类型,复杂引用类型的实例内存统计需要额外逻辑。
为什么Marshal.SizeOf会报错?
Marshal.SizeOf是用于计算非托管类型的内存大小,而你使用的是托管Object数组,且元素类型不固定,无法自动推断非托管类型,因此会抛出错误,不适合用来统计托管数组的内存。
内容的提问来源于stack exchange,提问作者user235627
相关产品推荐
相关产品推荐

