0

There is Large Object Heap in .NET for objects with size more than 85kb. As I understand size of object in heap calculated like this

  1. size of all properties and fields of primitive types and instances of value types (because they are stored inside parent instance)
  2. size of references to other instances of classes (because they are stored separately).

Examples:

  1. 10 objects of reference type (each 10kb) and one object of reference type which contains all of them => all objects should not be put into LOH
  2. 2 objects of reference type (each 86kb) and object of reference type which contains all of them => 2 objects in LOH but last one in usual heap

Is it correct calculation schema? Are my examples correct?

trincot
  • 317,000
  • 35
  • 244
  • 286
mtkachenko
  • 5,389
  • 9
  • 38
  • 68
  • May depend on a) the implementation of the list and b) Whether by "object" you're specifically trying to exclude value types. If the list is backed by an array and the objects are value types, then in (1) a single 100mb allocation will be required for the array. – Damien_The_Unbeliever Aug 21 '17 at 10:16
  • @Damien_The_Unbeliever Yes, I know that in case of pure array all items will be stored inline so heap need to allocate one place in memory for all items. Hm, it looks like my example with list is incorrect because under the hood list uses array. I will fix my examples a bit. – mtkachenko Aug 21 '17 at 10:21
  • 1
    I thought the LOH was for allocations over 85,000 bytes? That isn't 65MB. – Adam Houldsworth Aug 21 '17 at 10:23
  • @AdamHouldsworth you're right. – mtkachenko Aug 21 '17 at 10:25
  • @mtkachenko If I read this correctly, assuming everything is a `class` not a `struct`, your list should not be in the LOH, but each of your objects will be. If the objects are value types, the list goes into the LOH too. – Adam Houldsworth Aug 21 '17 at 10:26
  • @AdamHouldsworth I think the same. And I've fixed some ambiguities. – mtkachenko Aug 21 '17 at 10:28
  • @Damien_The_Unbeliever In my 1st comment I forgot to add "all items will be stored inline in case of value type". – mtkachenko Aug 21 '17 at 10:30
  • 1
    @mtkachenko It's not 85MB, it's 85KB. – Adam Houldsworth Aug 21 '17 at 10:30

1 Answers1

1

The allocation cost of a reference type in the CLR is comprised of a fixed overhead (dependent on architecture) plus the total amount of its members (all are eventually values, even references, 4-byte or 8-byte).

Refer to: What is the memory overhead of a .NET Object

It does not allocate the memory space of a referred object, just the reference value.

If you allocate a 10KB object, it won't hit the LOH.

If you allocate an array of 10 x 10KB classes, neither the list nor the objects will be in the LOH. The list will in fact be an array of 10 x size of reference for architecture.

If your class was a struct, the list would include the memory space required to house the 10KB struct, 10 times, which in theory would plonk the list (and by virtue of value-types, the objects too) on the LOH.

Don't forget, List<T> allocates space based on an algorithm (currently, x*2). It isn't what you put in the list that takes the space, but how much Capacity the list currently has.

The LOH allocation limit is an implementation detail of the runtime and could potentially change. It's interesting to see how it works, but don't build anything that relies on how it currently works.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187