dotnet/wpf · critical · OutOfMemoryException

OutOfMemoryException

Error message

OutOfMemoryException

What it means

During Span<T>.Set, when an updated region leaves part of an existing span ([fs]) intact, the span list must be grown by one via Resize. If Resize returns false (allocation failure), the code throws OutOfMemoryException to signal it could not complete the operation.

Solutions

  1. Reduce memory pressure in the process (free objects, use 64-bit, increase memory limits)
  2. Batch span insertions so fewer splits/resizes occur
  3. Treat as fatal allocation failure: catch OOM only to save state and exit gracefully
Defensive patterns

Strategy: try-catch

Validate before calling

// no pre-call validation available; monitor process memory before large layout operations
if (GC.GetTotalMemory(false) > memoryBudget) { /* free memory first */ }

Try / catch

try {
    spanCollection.Set(value, length);
} catch (OutOfMemoryException) {
    // abort operation; release resources; do not retry in-process
}

Prevention

When it happens

Trigger: Inserting/setting a range in a SparseSpanCollection that splits an existing span at an interior point while the internal span list cannot grow (its Resize fails).

Common situations: Very large or highly fragmented span collections exhausting internal capacity, e.g. extreme memory pressure while assembling large text runs.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/472b51b7df262e40. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Generic/Span.cs:232

                length = lc + _spanList[ls].Length - first;
                lc += _spanList[ls].Length;
                ls++;
            }

            // If no old Spans remain beyond area affected by update, handle easily:

            if (ls >= Count)
            {
                // None of the old span list extended beyond the update region

                if (fc < first)
                {
                    // Updated region leaves some of [fs]

                    if (Count != fs + 2)
                    {
                        if (!Resize(fs + 2))
                            throw new OutOfMemoryException();
                    }

                    Span<T> currentSpan = _spanList[fs];
                    _spanList[fs] = new Span<T>(currentSpan.Value, first - fc);
                    _spanList[fs + 1] = new Span<T>(value, length);
                }
                else
                {
                    // Updated item replaces [fs]
                    if (Count != fs + 1)
                    {
                        if (!Resize(fs + 1))
                            throw new OutOfMemoryException();
                    }

                    _spanList[fs] = new Span<T>(value, length);
                }

View on GitHub (pinned to 81131a70a4)