内存平铺管理和大对象C#

5

我有一组图像,存储在一个Int16类型的三维数组中,我可以缓存的图像数量可以达到600张或更多,这会影响内存性能和垃圾回收性能。我听说过内存分块可以增强内存管理,因为它将子数组元素设置在单独的块中。
- 我可以在我的情况下使用内存分块吗?
- 如果可以,我该如何使用它?


1
你的数组是如何定义的?是使用 new short[n][][] 还是 new short[x,y,z]?换句话说,它是真正的多维数组还是交错数组?你如何知道它会影响垃圾回收性能? - svick
1
600个对象算不了什么。拿一个内存分析器来看看到底发生了什么。 - sisve
@svick 我的数组是以 short[x,y,z] 的形式存在的,因为我已经搜索了很多关于内存泄漏的原因,发现大对象会影响GC的性能,有些人在这种情况下必须调用 GC.Collect,那么 short[x,y,z] 和 short[x][y][z] 哪个更好呢?感谢您的回复。 - Sara S.
@Simon,它们是医学图像,因此在某些情况下所需的总内存可能超过200MB。问题在于我将它们全部缓存到一个3D数组中,而不是作为单独的图像。 - Sara S.
1
大约85kb以上的数组(实现细节在垃圾收集中)存储在大对象堆(LOH)中。 LOH会被回收(旧对象被删除),但不会被压缩(“碎片整理”)。您考虑过使用内存映射[临时]文件吗?使用哪种类型的缓存?您如何使用这些图像? - sisve
哦,我不明白你指的是内存映射文件。但我的应用程序需要将缓存的体积(3D数组)加载到虚拟内存中,因为我需要一直从这些图像集生成图像。我正在进行多平面重建。 - Sara S.
2个回答

3

我能在我的情况下使用内存平铺吗?

可以。一个 int16 [,,] 的三维数组必须是一个连续的内存块。将其切片,它们就会变得更小。([][,])。

其余的取决于您的确切需求。


所以,short [x][y,z] 比 [x,y,z] 更好。而最好的是 short [x][y][z],这是我理解的对吗? - Sara S.
2
@Sara,这远非那么简单。哪种形式更好取决于你具体在做什么。 - svick
是的。使用内存更好,因为它不是一个大块(每个数组都是一个),但最佳大小取决于您的确切需求。这很复杂。例如,我使用高达4mb的缓冲区页面进行回收利用(有未使用的队列)。 - TomTom
我认为人们也应该看看这个问题,以了解在3D情况下节省内存的开销:https://dev59.com/dnRB5IYBdhLWcg3wiHll - Sara S.

1
垃圾收集需要尽可能地减少收集的内容。多维数组将被视为单个分配:
short[,,] a = new short[2,3,4];

一个锯齿数组将使用许多不同的分配。它较小的分配大小可能更快地进行分配,但在收集期间可能会对GC造成更大的压力:
short[][][] a = new short[2][][];

我以前从未听说过“内存平铺”,如果您能解释一下它是什么,我可能会更好地回答您的问题。

许多计算机应用程序需要操作大型数据数组。由于内存访问模式不佳,这些应用程序在分页虚拟内存(VM)系统下可能表现不佳。解决此问题的一种方法是平铺,这是一种技术,其中将数组分成子数组,这些子数组与VM页面一一映射。 - Sara S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接