Investigating an OutOfMemoryException
Originally posted at 1/5/2011
I finally got a reliable reproduction for a repeated error, but I have to say, just based on the initial impression, something very strange is going on.
The stack trace was a bit more interesting:
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at System.String.GetStringForStringBuilder(String value, Int32 startIndex, Int32 length, Int32 capacity) at System.Text.StringBuilder.GetNewString(String currentString, Int32 requiredLength) at System.Text.StringBuilder.Append(String value) at System.Text.RegularExpressions.RegexReplacement.ReplacementImpl(StringBuilder sb, Match match) at System.Text.RegularExpressions.RegexReplacement.Replace(Regex regex, String input, Int32 count, Int32 startat) at System.Text.RegularExpressions.Regex.Replace(String input, String replacement, Int32 count, Int32 startat) at System.Text.RegularExpressions.Regex.Replace(String input, String replacement) at System.Text.RegularExpressions.Regex.Replace(String input, String pattern, String replacement) at HibernatingRhinos.Profiler.BackEnd.SqlStatementProcessor.ReplaceParametersWithValues(String statement, Boolean useComment)
I put a breakpoint in the appropriate place, and discovered that the error occurred in:
- A SQL Statement that was 190 kilobytes in size
- It had 4,060 parameters
Now, let us look at the actual code:
private string ReplaceParametersWithValues(string statement, bool useComment) { if (sqlStatement.Parameters == null) return statement; foreach (var parameter in sqlStatement.Parameters .Where(x => x != null && x.Name.Empty() == false) .OrderByDescending(x => x.Name.Length)) { var patternNameSafeForRegex = Regex.Escape(parameter.Name); var pattern = patternNameSafeForRegex + @"(?![\d|_])"; //static Regex methods will cache the regex, so we don't need to worry about that var replacement = useComment ? parameter.Value + " /* " + parameter.Name + " */" : parameter.Value; statement = Regex.Replace(statement, pattern, replacement); } return statement; }
The problem is that:
- There is no heavy memory pressure.
- While the string is big, it is not that big.
- In practice, there is a single replacement for each parameter.
Just for fun, I wasn’t able to reproduce the issue without running the full NH Prof application.
I solved the issue, but I am not entirely pleased with the way I solved it. (That is tomorrow’s post)
Any ideas how to reproduce this?
Any elegant ideas on how to solve this?

Comments
Comment preview