Skip to content

Commit 3b06559

Browse files
committed
Modified ByteArrayBuilder.Clear() to downsize its buffer if it has grown too large
One potential problem with reusing ByteArrayBuilders is that, because they can grow for some abnormally long tokens/lines/commands/etc, those oversized buffers will remain referenced by the ImapStream/ImapEngine until they are disposed which could be the life of the program. If we oportunistically scale back the size of the buffers when they are Clear()'d, then we can periodically reduce memory usage and allow those larger buffers to be used elsewhere.
1 parent 6da7279 commit 3b06559

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

MailKit/ByteArrayBuilder.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,20 @@
2727
using System;
2828
using System.Text;
2929
using System.Buffers;
30+
using System.Runtime.CompilerServices;
3031

3132
namespace MailKit
3233
{
3334
class ByteArrayBuilder : IDisposable
3435
{
36+
readonly int initialCapacity;
3537
byte[] buffer;
3638
int length;
3739

38-
public ByteArrayBuilder (int initialCapacity)
40+
public ByteArrayBuilder (int capacity)
3941
{
40-
buffer = ArrayPool<byte>.Shared.Rent (initialCapacity);
42+
buffer = ArrayPool<byte>.Shared.Rent (capacity);
43+
initialCapacity = capacity;
4144
length = 0;
4245
}
4346

@@ -54,6 +57,7 @@ public byte[] GetBuffer ()
5457
return buffer;
5558
}
5659

60+
[MethodImpl (MethodImplOptions.AggressiveInlining)]
5761
void EnsureCapacity (int capacity)
5862
{
5963
if (capacity > buffer.Length) {
@@ -79,6 +83,11 @@ public void Append (byte[] text, int startIndex, int count)
7983

8084
public void Clear ()
8185
{
86+
if (buffer.Length > initialCapacity * 4) {
87+
ArrayPool<byte>.Shared.Return (buffer);
88+
buffer = ArrayPool<byte>.Shared.Rent (initialCapacity);
89+
}
90+
8291
length = 0;
8392
}
8493

0 commit comments

Comments
 (0)