-
Notifications
You must be signed in to change notification settings - Fork 317
Description
Describe the bug
Fetching a row from database which has varchar(max) typed column and contains about 1Mb of text causes ~8GB of garbage collector pressure.
I believe this issue is related to: #1864
As you can see from the screenshot of our real application this single method of this library dominates the memory usage:
Exception message:
Stack trace (v5.2.0-preview3.23201.1):
> System.Char[]
Objects : n/a
Bytes : 1751536296
>99,9% Rent • 1,63 GB / 1,63 GB • System.Buffers.TlsOverPerCoreLockedStacksArrayPool<T>.Rent(Int32)
>99,9% TryReadPlpUnicodeChars • 1,63 GB / - • Microsoft.Data.SqlClient.TdsParser.TryReadPlpUnicodeChars(Char[], Int32, Int32, TdsParserStateObject, Int32, Boolean, Boolean)
>99,9% TryReadSqlStringValue • 1,63 GB / - • Microsoft.Data.SqlClient.TdsParser.TryReadSqlStringValue(SqlBuffer, Byte, Int32, Encoding, Boolean, TdsParserStateObject)
>99,9% TryReadSqlValue • 1,63 GB / - • Microsoft.Data.SqlClient.TdsParser.TryReadSqlValue(SqlBuffer, SqlMetaDataPriv, Int32, TdsParserStateObject, SqlCommandColumnEncryptionSetting, String, SqlCommand)
>99,9% TryReadColumnInternal • 1,63 GB / - • Microsoft.Data.SqlClient.SqlDataReader.TryReadColumnInternal(Int32, Boolean, Boolean)
>99,9% ReadAsyncExecute • 1,63 GB / - • Microsoft.Data.SqlClient.SqlDataReader.ReadAsyncExecute(Task, Object)
>99,9% ContinueAsyncCall • 1,63 GB / - • Microsoft.Data.SqlClient.SqlDataReader.ContinueAsyncCall<T>(Task, SqlDataReader+SqlDataReaderBaseAsyncCallContext<T>)
>99,9% InnerInvoke • 1,63 GB / - • System.Threading.Tasks.ContinuationResultTaskFromResultTask<TAntecedentResult, TResult>.InnerInvoke()
>99,9% <.cctor>b__272_0 • 1,63 GB / - • System.Threading.Tasks.Task+<>c.<.cctor>b__272_0(Object)
>99,9% RunFromThreadPoolDispatchLoop • 1,63 GB / - • System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread, ExecutionContext, ContextCallback, Object)
>99,9% ExecuteWithThreadLocal • 1,63 GB / - • System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task, Thread)
>99,9% ExecuteEntryUnsafe • 1,63 GB / - • System.Threading.Tasks.Task.ExecuteEntryUnsafe(Thread)
>99,9% ExecuteFromThreadPool • 1,63 GB / - • System.Threading.Tasks.Task.ExecuteFromThreadPool(Thread)
>99,9% Dispatch • 1,63 GB / - • System.Threading.ThreadPoolWorkQueue.Dispatch()
>99,9% WorkerThreadStart • 1,63 GB / - • System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()
>99,9% StartCallback • 1,63 GB / - • System.Threading.Thread.StartCallback()
► >99,9% [AllThreadsRoot] • 1,63 GB / - • [AllThreadsRoot]
► <0,01% Grow • 104,4 KB / - • System.Text.ValueStringBuilder.Grow(Int32)
To reproduce
I created a public sample console application where this issue can be reproduced
The situation is better in v5.2.0-preview3.23201.1 but in my opinion its still not good enough, is there anything else what can we done here to reduce the memory allocations?
https://github.com/Havunen/MicrosoftSqlDriverGcBug
Expected behavior
As little memory is allocated as possible, allocating gigabytes of memory for 1 megabyte of string sounds wrong.
Further technical details
Microsoft.Data.SqlClient version 5.1.1
.NET 6.0.21
SQL Server version: SQL Server 2019, 150
Operating system: Windows 11
