Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

LOH fragmentation when user post form with section content more than 85KB #597

Closed
@yuwaMSFT

Description

@yuwaMSFT

Post a multipart form with content more than 85KB in each section would cause heavy LOH fragmentation in MVC app.

Post a multipart form with 100 sections, each containing random sized content with an average of 120KB.

After the first request:

_         segment             begin         allocated              size
0000021c56c50000  0000021c56c51000  0000021c582fa2a0  0x16a92a0(23761568)
Total Size:              Size: 0x1f0bcb8 (32554168) bytes.
Statistics:
              MT    Count    TotalSize Class Name
0000021c46a5d8e0      **107         3204      **Free
00007ffbbe854418        9       146136 System.Object[]
00007ffbbe84e210       16      2097536 System.Byte[]
00007ffbbe862498      ** 81     21514154 **System.String
_

After the 2nd request:

_Large object heap starts at 0x0000021c56c51000
         segment             begin         allocated              size
0000021c56c50000  0000021c56c51000  0000021c5983f700  0x2bee700(46065408)
Statistics:
              MT    Count    TotalSize Class Name
0000021c46a5d8e0      **194         5814      **Free
00007ffbbe854418        9       146136 System.Object[]
00007ffbbe84e210       22      2884112 System.Byte[]
00007ffbbe862498      **162     43028308 **System.String
_

After the 3rd request:

_Large object heap starts at 0x0000021c56c51000
         segment             begin         allocated              size
0000021c56c50000  0000021c56c51000  0000021c5983f700  0x2bee700(46065408)
Total Size:              Size: 0x362f488 (56816776) bytes.
Statistics:
              MT    Count    TotalSize Class Name
0000021c46a5d8e0     ** 276         8274      **Free
00007ffbbe854418        9       146136 System.Object[]
00007ffbbe84e210       23      3015208 System.Byte[]
00007ffbbe862498     ** 243     64542462 **System.String_

So for each request we are adding the large string in LOH for each section (field) of the form. Also, look at the "Free" type. They are mostly 30 bytes in LOH accompany each large string. It may be some string interning.

For the string object, basically we are reading each section (field) into a string:

_                        else if (HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            MediaTypeHeaderValue mediaType;
                            MediaTypeHeaderValue.TryParse(section.ContentType, out mediaType);
                            var encoding = FilterEncoding(mediaType?.Encoding);
                            using (var reader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                **var value = await reader.ReadToEndAsync**();
                                formAccumulator.Append(key, value);
                            }
                        }_

This can be easily explored to cause the server to run OOM. Security concern as well.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions