Skip to content

[Breaking change]: Update MemoryStream max capacity #49545

@jozkee

Description

@jozkee

[Breaking change]: MemoryStream maximum capacity updated and exception behavior changed

Description

Starting in .NET 11 Preview 1, the System.IO.MemoryStream class has been updated to enforce a maximum capacity of 0x7FFFFFC7 bytes, which is the actual maximum length of a byte array supported by the CLR. Previously, MemoryStream allowed capacities up to int.MaxValue (0x7FFFFFFF), which could result in an OutOfMemoryException when attempting to allocate memory beyond the supported limit.

Additionally, the exception behavior has changed when attempting to set a MemoryStream's capacity or length beyond the new maximum. Instead of throwing an OutOfMemoryException, the MemoryStream now throws an ArgumentOutOfRangeException in these scenarios (this is the key difference).

This change ensures that MemoryStream behaves consistently with the CLR's actual memory allocation limits and provides a more accurate exception type for invalid capacity or length values.

Version

.NET 11 Preview 1

Previous behavior

  • MemoryStream allowed capacities up to int.MaxValue (0x7FFFFFFF), which could result in an OutOfMemoryException when attempting to allocate memory beyond the CLR's supported limit of 0x7FFFFFC7.
  • When setting the capacity or length of a MemoryStream to a value greater than the supported limit, an OutOfMemoryException was thrown.

Example:

var stream = new MemoryStream();
stream.SetLength(int.MaxValue); // Throws OutOfMemoryException

New behavior

  • MemoryStream now enforces a maximum capacity of 0x7FFFFFC7 bytes. Attempting to set the capacity or length beyond this limit will throw an ArgumentOutOfRangeException.
  • The exception type for invalid capacity or length values has changed from OutOfMemoryException to ArgumentOutOfRangeException.

Example:

var stream = new MemoryStream();
stream.SetLength(int.MaxValue); // Throws ArgumentOutOfRangeException

Reason for change

This change was introduced to align MemoryStream's behavior with the actual memory allocation limits of the CLR. The previous behavior allowed developers to specify capacities or lengths that exceeded the supported limit, leading to runtime failures with less descriptive exceptions (OutOfMemoryException). By capping the maximum capacity and throwing ArgumentOutOfRangeException, the change improves runtime reliability and provides clearer feedback to developers.

Recommended action

Developers should review any code that sets the capacity or length of a MemoryStream to ensure it does not exceed the new maximum of 0x7FFFFFC7 bytes.

If your code was only catching OutOfMemoryException when working with MemoryStream capacity or length operations, you should update it to also catch ArgumentOutOfRangeException. For example:

var stream = new MemoryStream();
try
{
    stream.SetLength(someLength);
}
catch (OutOfMemoryException)
{
    // Handle out of memory scenario
}
catch (ArgumentOutOfRangeException)
{
    // Handle invalid capacity/length scenario
}

You can also add a check before setting the capacity or length to avoid the exception:

const int MaxMemoryStreamCapacity = 0x7FFFFFC7;

var stream = new MemoryStream();
long newLength = int.MaxValue;

if (newLength > MaxMemoryStreamCapacity)
{
    throw new ArgumentOutOfRangeException(nameof(newLength), $"Length cannot exceed {MaxMemoryStreamCapacity} bytes.");
}

stream.SetLength(newLength);

Affected APIs

  • System.IO.MemoryStream.Capacity
  • System.IO.MemoryStream.SetLength(long)
  • System.IO.MemoryStream.ctor(int)

Category

  • Behavioral change: Existing binaries might behave differently at runtime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions