Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. Memory utilization of MemoryStream

Memory utilization of MemoryStream

Scheduled Pinned Locked Moved .NET (Core and Framework)
performancetutorialquestion
7 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    elix545
    wrote on last edited by
    #1

    Why MemoryStream object uses double the memory? For example, whether the capacity of MemoryStream is 1GB in Task Manager I see that is consuming 2GB.

    Module Module1

    Sub Main()
        Dim ObjMemoryStream As System.IO.MemoryStream
        ObjMemoryStream = New System.IO.MemoryStream()
        System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
        System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
    
        Dim j As Integer
    
        For i As Integer = 0 To 1073741824 Step 1
            If (i Mod 256) = 0 Then j = 0 Else j = i Mod 256
            ObjMemoryStream.WriteByte(j)
        Next i
    
        System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
    
        Dim ObjFileStream As System.IO.FileStream
        ObjFileStream = System.IO.File.Create("C:\\TEST.TXT", 1024)
    
        Dim ObjBinaryWriter As System.IO.BinaryWriter
        ObjBinaryWriter = New System.IO.BinaryWriter(ObjFileStream, System.Text.Encoding.ASCII)
    
        ObjMemoryStream.Position = 0
    
        ObjBinaryWriter.Write(ObjMemoryStream.ToArray())
    
        ObjBinaryWriter.Flush()
        ObjBinaryWriter.Close()
    
        System.Console.ReadKey()
    
    End Sub
    

    End Module

    P D J 3 Replies Last reply
    0
    • E elix545

      Why MemoryStream object uses double the memory? For example, whether the capacity of MemoryStream is 1GB in Task Manager I see that is consuming 2GB.

      Module Module1

      Sub Main()
          Dim ObjMemoryStream As System.IO.MemoryStream
          ObjMemoryStream = New System.IO.MemoryStream()
          System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
          System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
      
          Dim j As Integer
      
          For i As Integer = 0 To 1073741824 Step 1
              If (i Mod 256) = 0 Then j = 0 Else j = i Mod 256
              ObjMemoryStream.WriteByte(j)
          Next i
      
          System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
      
          Dim ObjFileStream As System.IO.FileStream
          ObjFileStream = System.IO.File.Create("C:\\TEST.TXT", 1024)
      
          Dim ObjBinaryWriter As System.IO.BinaryWriter
          ObjBinaryWriter = New System.IO.BinaryWriter(ObjFileStream, System.Text.Encoding.ASCII)
      
          ObjMemoryStream.Position = 0
      
          ObjBinaryWriter.Write(ObjMemoryStream.ToArray())
      
          ObjBinaryWriter.Flush()
          ObjBinaryWriter.Close()
      
          System.Console.ReadKey()
      
      End Sub
      

      End Module

      P Offline
      P Offline
      Pete OHanlon
      wrote on last edited by
      #2

      First of all, you don't see the MemoryStream in isolation as far as memory consumption goes. There's the rest of the program, including all the assemblies that get loaded in - they all take up memory. Secondly, don't rely on Task Manager to determine memory profile. Task manager is a notoriously poor way of judging memory usage. Part of the reason for this is that .NET grabs more memory than it needs - this is to give the application room "to grow into" as it runs. Memory allocation is an expensive operation, so having your application grab just the bytes it needs while it's running would be a waste of time.

      1 Reply Last reply
      0
      • E elix545

        Why MemoryStream object uses double the memory? For example, whether the capacity of MemoryStream is 1GB in Task Manager I see that is consuming 2GB.

        Module Module1

        Sub Main()
            Dim ObjMemoryStream As System.IO.MemoryStream
            ObjMemoryStream = New System.IO.MemoryStream()
            System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
            System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
        
            Dim j As Integer
        
            For i As Integer = 0 To 1073741824 Step 1
                If (i Mod 256) = 0 Then j = 0 Else j = i Mod 256
                ObjMemoryStream.WriteByte(j)
            Next i
        
            System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
        
            Dim ObjFileStream As System.IO.FileStream
            ObjFileStream = System.IO.File.Create("C:\\TEST.TXT", 1024)
        
            Dim ObjBinaryWriter As System.IO.BinaryWriter
            ObjBinaryWriter = New System.IO.BinaryWriter(ObjFileStream, System.Text.Encoding.ASCII)
        
            ObjMemoryStream.Position = 0
        
            ObjBinaryWriter.Write(ObjMemoryStream.ToArray())
        
            ObjBinaryWriter.Flush()
            ObjBinaryWriter.Close()
        
            System.Console.ReadKey()
        
        End Sub
        

        End Module

        D Offline
        D Offline
        Dave Kreskowiak
        wrote on last edited by
        #3

        That's how much memory the MemoryStream has set aside for use. Since you didn't specify a capacity, it starts off with 256 bytes by default. As the stream is used and the current capacity is exceeded, it reallocates it's internal buffer and sets a new size larger than the current capacity. That new size is always twice the last size it used. Arrays in .NET are immutable. Once created, you cannot change the size of an array. That limitation applies to everything in the .NET Framework, including the buffer used by MemoryStream. In order to increase the size, a new array of some size must be created and all the elements of the previous array copied to it, then the previous array is destroyed.

        A guide to posting questions on CodeProject[^]
        Dave Kreskowiak

        E 1 Reply Last reply
        0
        • D Dave Kreskowiak

          That's how much memory the MemoryStream has set aside for use. Since you didn't specify a capacity, it starts off with 256 bytes by default. As the stream is used and the current capacity is exceeded, it reallocates it's internal buffer and sets a new size larger than the current capacity. That new size is always twice the last size it used. Arrays in .NET are immutable. Once created, you cannot change the size of an array. That limitation applies to everything in the .NET Framework, including the buffer used by MemoryStream. In order to increase the size, a new array of some size must be created and all the elements of the previous array copied to it, then the previous array is destroyed.

          A guide to posting questions on CodeProject[^]
          Dave Kreskowiak

          E Offline
          E Offline
          elix545
          wrote on last edited by
          #4

          I think that object are storing the the data using two memory byte, please check the next example:

          Module Module1

          Sub Main()         
              Dim ObjMemoryStream As System.IO.MemoryStream
              ObjMemoryStream = New System.IO.MemoryStream(1073741825)
              System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
              System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
          
              Dim j As Integer
          
              For i As Integer = 0 To 1073741824 Step 1
                  If (i Mod 256) = 0 Then j = 0 Else j = i Mod 256
                  ObjMemoryStream.WriteByte(j)
              Next i
          
              System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
              System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
          
              Dim ObjFileStream As System.IO.FileStream
              ObjFileStream = System.IO.File.Create("C:\\TEST.txt", 1024)
          
              Dim ObjBinaryWriter As System.IO.BinaryWriter
              ObjBinaryWriter = New System.IO.BinaryWriter(ObjFileStream, System.Text.Encoding.ASCII)
          
              ObjMemoryStream.Position = 0
          
              ObjBinaryWriter.Write(ObjMemoryStream.ToArray())
          
              ObjBinaryWriter.Flush()
              ObjBinaryWriter.Close()
          
              System.Console.ReadKey()
          End Sub
          

          End Module

          D 1 Reply Last reply
          0
          • E elix545

            I think that object are storing the the data using two memory byte, please check the next example:

            Module Module1

            Sub Main()         
                Dim ObjMemoryStream As System.IO.MemoryStream
                ObjMemoryStream = New System.IO.MemoryStream(1073741825)
                System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
                System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
            
                Dim j As Integer
            
                For i As Integer = 0 To 1073741824 Step 1
                    If (i Mod 256) = 0 Then j = 0 Else j = i Mod 256
                    ObjMemoryStream.WriteByte(j)
                Next i
            
                System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
                System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
            
                Dim ObjFileStream As System.IO.FileStream
                ObjFileStream = System.IO.File.Create("C:\\TEST.txt", 1024)
            
                Dim ObjBinaryWriter As System.IO.BinaryWriter
                ObjBinaryWriter = New System.IO.BinaryWriter(ObjFileStream, System.Text.Encoding.ASCII)
            
                ObjMemoryStream.Position = 0
            
                ObjBinaryWriter.Write(ObjMemoryStream.ToArray())
            
                ObjBinaryWriter.Flush()
                ObjBinaryWriter.Close()
            
                System.Console.ReadKey()
            End Sub
            

            End Module

            D Offline
            D Offline
            Dave Kreskowiak
            wrote on last edited by
            #5

            No, it's not. What you're storing is irrelevant. If you keep exceeding the capacity of the MemoryStream, it will keep allocating new arrays, twice as large as the last, until it can't grow any more (2GB). These are the sizes the MemoryStream went through after you created it and keep adding more and more data to it:

            256
            512
            1024
            2048
            4096
            8192
            16384
            32768
            65536
            131072
            262144
            524288
            1048576
            2097152
            4194304
            8388608
            16777216
            33554432
            67108864
            134217728
            268435456
            536870912
            1073741824
            2147483648

            Oh, look at that. It managed to hit 2GB in size right after you added 1073741824 bytes of information to it. It's allocating bigger and bigger blocks of memory because it has no way of knowing how big to make the array to that it fits your data perfectly. If you want to keep it from getting to 2GB of memory, allocate the MemoryStream with the expected size as a parameter, say 1.5GB:

            Dim ms As New MemoryStream(1610612736)
            

            Now, if you exceed that, the MemoryStream will try to reallocate itself using twice the size you initially specified and that will lead to an OutOfMemory exception. You can NOT look in Task Manager to see how much memory your app is using. It's telling you how much memory the .NET CLR as RESERVED for your app. This will always be larger than what your app is actually using.

            A guide to posting questions on CodeProject[^]
            Dave Kreskowiak

            E 1 Reply Last reply
            0
            • D Dave Kreskowiak

              No, it's not. What you're storing is irrelevant. If you keep exceeding the capacity of the MemoryStream, it will keep allocating new arrays, twice as large as the last, until it can't grow any more (2GB). These are the sizes the MemoryStream went through after you created it and keep adding more and more data to it:

              256
              512
              1024
              2048
              4096
              8192
              16384
              32768
              65536
              131072
              262144
              524288
              1048576
              2097152
              4194304
              8388608
              16777216
              33554432
              67108864
              134217728
              268435456
              536870912
              1073741824
              2147483648

              Oh, look at that. It managed to hit 2GB in size right after you added 1073741824 bytes of information to it. It's allocating bigger and bigger blocks of memory because it has no way of knowing how big to make the array to that it fits your data perfectly. If you want to keep it from getting to 2GB of memory, allocate the MemoryStream with the expected size as a parameter, say 1.5GB:

              Dim ms As New MemoryStream(1610612736)
              

              Now, if you exceed that, the MemoryStream will try to reallocate itself using twice the size you initially specified and that will lead to an OutOfMemory exception. You can NOT look in Task Manager to see how much memory your app is using. It's telling you how much memory the .NET CLR as RESERVED for your app. This will always be larger than what your app is actually using.

              A guide to posting questions on CodeProject[^]
              Dave Kreskowiak

              E Offline
              E Offline
              elix545
              wrote on last edited by
              #6

              Thank you very mush.:thumbsup:

              1 Reply Last reply
              0
              • E elix545

                Why MemoryStream object uses double the memory? For example, whether the capacity of MemoryStream is 1GB in Task Manager I see that is consuming 2GB.

                Module Module1

                Sub Main()
                    Dim ObjMemoryStream As System.IO.MemoryStream
                    ObjMemoryStream = New System.IO.MemoryStream()
                    System.Console.WriteLine("Capacity: {0}", ObjMemoryStream.Capacity.ToString())
                    System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
                
                    Dim j As Integer
                
                    For i As Integer = 0 To 1073741824 Step 1
                        If (i Mod 256) = 0 Then j = 0 Else j = i Mod 256
                        ObjMemoryStream.WriteByte(j)
                    Next i
                
                    System.Console.WriteLine("Length: {0}", ObjMemoryStream.Length.ToString())
                
                    Dim ObjFileStream As System.IO.FileStream
                    ObjFileStream = System.IO.File.Create("C:\\TEST.TXT", 1024)
                
                    Dim ObjBinaryWriter As System.IO.BinaryWriter
                    ObjBinaryWriter = New System.IO.BinaryWriter(ObjFileStream, System.Text.Encoding.ASCII)
                
                    ObjMemoryStream.Position = 0
                
                    ObjBinaryWriter.Write(ObjMemoryStream.ToArray())
                
                    ObjBinaryWriter.Flush()
                    ObjBinaryWriter.Close()
                
                    System.Console.ReadKey()
                
                End Sub
                

                End Module

                J Offline
                J Offline
                JonB
                wrote on last edited by
                #7

                I assume you're looking at the process size when you hit the ReadKey(). Your ObjMemoryStream will be 1GB + 1 byte big (you start from 0). Then you evaluate ObjMemoryStream.ToArray(). That will create an array (Help: "This method returns a copy of the contents of the MemoryStream as a byte array"), also of size 1GB-odd. (You don't know when .NET will garbage-collect that, and process sizes often don't shrink anyway.) Don't convert your memory stream to an array! Try something like ObjMemoryStream.CopyTo() instead.

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups