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
Description
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.