How do I force release memory occupied by MemoryStream?

后端 未结 4 630
北恋
北恋 2021-02-07 12:02

I have the following code:

const int bufferSize = 1024 * 1024;
var buffer = new byte[bufferSize];
for (int i = 0; i < 10; i++)
{
    const int writesCount = 4         


        
4条回答
  •  一生所求
    2021-02-07 12:46

    I don't think the problem is the garbage collector not doing its job. If the GC is under memory pressure it should run and reclaim the 400 MBs you've just allocated.

    This is more likely down to the GC not finding a contigious 400 MB block.

    Rather, an “out of memory” error happens because the process is unable to find a large enough section of contiguous unused pages in its virtual address space to do the requested mapping.

    You should read Eric Lippert's blog entry "Out Of Memory" Does Not Refer to Physical Memory

    You're far better off doing both of the below.

    1. Reusing the memory block you've allocated (why are you creating another with the exact same size)
    2. Allocating much smaller chunks (less than 85KBs)

    Prior to Dotnet 4.5, Dotnet constructed two heaps, Small Object Heap (SOH) and Large Object Heap (LOH). See Large Object Hearp Improvements in .NET 4.5 by Brandon Bray. Your MemoryStream is being allocated in LOH, and not compacted (defragmented) for the duration of the process, making it much more likely that multiple calls to allocate this large amount of memory will throw an OutOfMemoryException

    The CLR manages two different heaps for allocation, the small object heap (SOH) and the large object heap (LOH). Any allocation greater than or equal to 85,000 bytes goes on the LOH. Copying large objects has a performance penalty, so the LOH is not compacted unlike the SOH. Another defining characteristic is that the LOH is only collected during a generation 2 collection. Together, these have the built-in assumption that large object allocations are infrequent.

提交回复
热议问题