我如何知道 .NET 中的大对象堆 (LOH) 中分配了结构数组?

发布于 2024-08-31 10:45:51 字数 397 浏览 8 评论 0原文

使用 CLR Profiler 进行一些实验后,我发现:

Node[,] n = new Node[100,23]; //'84,028 bytes, is not placed in LOH
Node[,] n = new Node[100,24]; //'86,428 bytes, is 

    public struct Node {
        public int Value;
        public Point Point;
        public Color Color;
        public bool Handled;
        public Object Tag;
    }

在运行时,我如何知道在大对象堆 (LOH) 中分配了结构数组(或任何数组)?

After some experimenation using CLR Profiler, I found that:

Node[,] n = new Node[100,23]; //'84,028 bytes, is not placed in LOH
Node[,] n = new Node[100,24]; //'86,428 bytes, is 

    public struct Node {
        public int Value;
        public Point Point;
        public Color Color;
        public bool Handled;
        public Object Tag;
    }

During run-time, how do I know an array of structures (or any array) was allocated in the Large Object Heap (LOH)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拿命拼未来 2024-09-07 10:45:51

任何大于 85,000 字节的对象都将存储在 LOH 上。这是一篇关于 .Net 内存管理

Any object larger than 85,000 bytes will be stored on the LOH. Here is a great blog post about .Net Memory Management.

别闹i 2024-09-07 10:45:51

分配后就可以知道。使用 GC.GetGeneration(object) 重载来获取对象所在的代号。对于 LOH,这将是 2。

Node[,] n = new Node[100,23]; 
// GC.GetGeneration(n) should give 0
Node[,] n = new Node[100,24]; 
// GC.GetGeneration(n) should give 2

注意,这有一些限制,并且绝不是生产代码的正确方法,我假设:如果如果您稍后查询该数字,该对象可能已经从 Gen 0 移动到 Gen 2。据我所知,无法区分 Gen2(小对象)堆和 LOH。此外,对于我测试过的所有 .NET 版本,LOH 上的对象返回的数量都是 2。但我在真正的规范中找不到这一点,所以这也可能是一个改变的问题。

You can find out right after allocation. Use the GC.GetGeneration(object) overload to get the generation number, the object lays in. For LOH this will be 2.

Node[,] n = new Node[100,23]; 
// GC.GetGeneration(n) should give 0
Node[,] n = new Node[100,24]; 
// GC.GetGeneration(n) should give 2

Note, this comes with some restrictions and is by no means a proper way for production code, I assume: If you query that number at a later point, the object may has been moved from Gen 0 up to Gen 2 already. There is no way I know of to distinguish between the Gen2 (small object) heap and LOH. Also, the number returned for objects on the LOH is 2 for all .NET versions I did test it with. But I couldn't find this in a real specification, so it may be a matter of change as well.

棒棒糖 2024-09-07 10:45:51

从您的评论来看,我认为您实际上不需要知道该对象是否会进入 LOH。当您真正想做的只是在用户输入“太大”的值时向用户显示警告时,这是否是应用程序速度减慢的实际原因并不重要。

因此,我建议采用更简单的方法:只需进行一些反复试验即可确定截止值。如果他们输入的尺寸超过您的试错值,则显示警告。

至于您的实际性能问题,您可以简单地分配一堆“较小”的一维数组,而不是分配一个大的二维数组。而不是:

Node[,] n = new Node[100,100]; // this will go the LOH

您会这样做:

Node[][] n = new Node[100][];
for(int i = 0; i < n.Length; i++) {
    n[i] = new Node[100];  // none of these will be on the LOH
}

您仍然拥有相同数量的节点,但 LOH 上不会发生任何事情。就我个人而言,我认为您可能会发现性能实际上不会有太大不同,但尝试一下可能是值得的。

From your comments, I don't think you actually need to know whether the object is going to go on the LOH or not. Whether or not that's the actual cause of your application's slowdown is kind of irrelevant when all you really want to do is display a warning to the user when they enter a value that's "too big".

So I would suggest something a bit simpler: just use a bit of trial-and-error to determine the cut-off value. If they enter a size over your trial-and-error value, display the warning.

As for your actual performance problems, instead of allocating one big two-dimensional array, you could simply allocate a bunch of "smaller" one dimensional arrays. Instead of:

Node[,] n = new Node[100,100]; // this will go the LOH

You'd do this:

Node[][] n = new Node[100][];
for(int i = 0; i < n.Length; i++) {
    n[i] = new Node[100];  // none of these will be on the LOH
}

You'd still have the same number of nodes in total, but nothing would go on the LOH. Personally, I think you will probably find that the performance is actually not going to be all that much different, but it might be worthwhile to just give it a try.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文