Performance problems typically arise from two areas: distribution and fragmentation.
Selection
Runtime guarantees clean memory, so it runs cleaning cycles. When you allocate a large object, this is most of the memory and starts adding milliseconds to a single distribution (to be honest, a simple distribution in .NET is actually very fast, so we usually never care about that).
Fragmentation occurs when LOH objects are distributed and then regenerated. Until recently, the GC could not reorganize memory to remove these โspacesโ of the old object, and thus could only match the next object in this gap if it was the same size or smaller. Recently, GC was able to seal LOH, which eliminates this problem, but takes time during compaction.
My assumption in your case is that you suffer from both problems and run GC sessions, but it depends on how often your code tries to highlight elements in LOH. If you do a lot of distributions, try the route of the object pool. If you cannot manage the pool efficiently (lumpy object lifetime or disparate usage patterns), try splitting the data you are working with to completely avoid this.
<h / "> Options
I came across two approaches to LOH:
- Avoid this.
- Use it, but understand that you use it and control it explicitly.
Avoid this
This includes fragmenting your large object (usually some array) into, well, pieces that fall under the LOH barrier. We do this by serializing large flows of objects. Works well, but the implementation will be specific to your environment, so I hesitate to provide a coded example.
Use him
A simple way to solve both distribution and fragmentation are objects with a long service life. Explicitly make an empty array (or arrays) of large size to accommodate your large object and do not dispose of it (or them). Leave it and reuse it as a pool of objects. You pay for this distribution, but you can do it either the first time you use it or while the application is idle, but you pay less for redistribution (because you do not redistribute) and reduce fragmentation problems because you do not constantly request allocation of material, and you do not return items (which primarily causes gaps).
However, maybe halfway. Reserve a memory partition for the object pool. Completed earlier, these allocations must be contiguous in memory, so you wonโt get any spaces and leave a tail of available memory for uncontrolled elements. Beware, although this obviously affects the working set of your application - the pool of objects takes up space, regardless of whether it is used or not.
<h / "> Resources
LOH is widely used on the Internet, but pay attention to the date of the resource. In recent versions of .NET, LOH got some love and improved. However, if you are using an older version, I think the resources on the network are pretty accurate, since LOH has never received any major updates since the creation of .NET 4.5 (ish).
For example, there is this article from 2008 http://msdn.microsoft.com/en-us/magazine/cc534993.aspx
And a summary of the improvements in .NET 4.5: http://blogs.msdn.com/b/dotnet/archive/2011/10/04/large-object-heap-improvements-in-net-4-5.aspx