diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs
index 8e0196b11..b71f05b2b 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs
@@ -57,7 +57,7 @@ private IEnumerable<bool> CreateStateMachine()
 				while (!input.TryGetBits(3, ref codeLengths, MetaCodeLengthIndex[i])) yield return false;
 			}
 
-			var metaCodeTree = new InflaterHuffmanTree(codeLengths);
+			var metaCodeTree = new InflaterHuffmanTree(codeLengths.AsSpan());
 
 			// Decompress the meta tree symbols into the data table code lengths
 			int index = 0;
@@ -113,8 +113,8 @@ private IEnumerable<bool> CreateStateMachine()
 			if (codeLengths[256] == 0)
 				throw new StreamDecodingException("Inflater dynamic header end-of-block code missing");
 
-			litLenTree = new InflaterHuffmanTree(new ArraySegment<byte>(codeLengths, 0, litLenCodeCount));
-			distTree = new InflaterHuffmanTree(new ArraySegment<byte>(codeLengths, litLenCodeCount, distanceCodeCount));
+			litLenTree = new InflaterHuffmanTree(codeLengths.AsSpan(0, litLenCodeCount));
+			distTree = new InflaterHuffmanTree(codeLengths.AsSpan(litLenCodeCount, distanceCodeCount));
 
 			yield return true;
 		}
diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs
index ed318824f..e6f2663f4 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs
@@ -1,6 +1,8 @@
 using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
 using System;
 using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
 
 namespace ICSharpCode.SharpZipLib.Zip.Compression
 {
@@ -13,6 +15,11 @@ public class InflaterHuffmanTree
 
 		private const int MAX_BITLEN = 15;
 
+		// see InflaterHuffmanTreeTest.GenerateTrees how to generate the sequence
+		// stored in DLL's static data section so no allocation occurs
+		private static ReadOnlySpan<byte> defLitLenTreeBytes => new byte[] { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8 };
+		private static ReadOnlySpan<byte> defDistTreeBytes => new byte[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
+
 		#endregion Constants
 
 		#region Instance Fields
@@ -24,52 +31,41 @@ public class InflaterHuffmanTree
 		/// <summary>
 		/// Literal length tree
 		/// </summary>
-		public static InflaterHuffmanTree defLitLenTree;
+		public static readonly InflaterHuffmanTree defLitLenTree = new InflaterHuffmanTree(defLitLenTreeBytes);
 
 		/// <summary>
 		/// Distance tree
 		/// </summary>
-		public static InflaterHuffmanTree defDistTree;
+		public static readonly InflaterHuffmanTree defDistTree = new InflaterHuffmanTree(defDistTreeBytes);
+
+		#region Constructors
 
-		static InflaterHuffmanTree()
+		/// <summary>
+		/// Constructs a Huffman tree from the array of code lengths.
+		/// </summary>
+		/// <param name = "codeLengths">
+		/// the array of code lengths
+		/// </param>
+		public InflaterHuffmanTree(IList<byte> codeLengths) : this(ListToSpan(codeLengths))
 		{
-			try
-			{
-				byte[] codeLengths = new byte[288];
-				int i = 0;
-				while (i < 144)
-				{
-					codeLengths[i++] = 8;
-				}
-				while (i < 256)
-				{
-					codeLengths[i++] = 9;
-				}
-				while (i < 280)
-				{
-					codeLengths[i++] = 7;
-				}
-				while (i < 288)
-				{
-					codeLengths[i++] = 8;
-				}
-				defLitLenTree = new InflaterHuffmanTree(codeLengths);
+		}
 
-				codeLengths = new byte[32];
-				i = 0;
-				while (i < 32)
-				{
-					codeLengths[i++] = 5;
-				}
-				defDistTree = new InflaterHuffmanTree(codeLengths);
+		private static ReadOnlySpan<byte> ListToSpan(IList<byte> codeLengths)
+		{
+#if NET6_0_OR_GREATER
+			if (codeLengths is List<byte> list)
+			{
+				return CollectionsMarshal.AsSpan(list);
 			}
-			catch (Exception)
+#endif
+			if (codeLengths is byte[] array)
 			{
-				throw new SharpZipBaseException("InflaterHuffmanTree: static tree length illegal");
+				return array;
 			}
-		}
 
-		#region Constructors
+			// slow path
+			return codeLengths.ToArray();
+		}
 
 		/// <summary>
 		/// Constructs a Huffman tree from the array of code lengths.
@@ -77,21 +73,20 @@ static InflaterHuffmanTree()
 		/// <param name = "codeLengths">
 		/// the array of code lengths
 		/// </param>
-		public InflaterHuffmanTree(IList<byte> codeLengths)
+		internal InflaterHuffmanTree(ReadOnlySpan<byte> codeLengths)
 		{
 			BuildTree(codeLengths);
 		}
 
 		#endregion Constructors
 
-		private void BuildTree(IList<byte> codeLengths)
+		private void BuildTree(ReadOnlySpan<byte> codeLengths)
 		{
-			int[] blCount = new int[MAX_BITLEN + 1];
-			int[] nextCode = new int[MAX_BITLEN + 1];
+			Span<int> blCount = stackalloc int[MAX_BITLEN + 1];
+			Span<int> nextCode = stackalloc int[MAX_BITLEN + 1];
 
-			for (int i = 0; i < codeLengths.Count; i++)
+			foreach (var bits in codeLengths)
 			{
-				int bits = codeLengths[i];
 				if (bits > 0)
 				{
 					blCount[bits]++;
@@ -136,20 +131,21 @@ private void BuildTree(IList<byte> codeLengths)
 				}
 			}
 
-			for (int i = 0; i < codeLengths.Count; i++)
+			for (var i = 0; i < codeLengths.Length; i++)
 			{
-				int bits = codeLengths[i];
+				var bits = codeLengths[i];
 				if (bits == 0)
 				{
 					continue;
 				}
+
 				code = nextCode[bits];
 				int revcode = DeflaterHuffman.BitReverse(code);
 				if (bits <= 9)
 				{
 					do
 					{
-						tree[revcode] = (short)((i << 4) | bits);
+						tree[revcode] = (short) ((i << 4) | bits);
 						revcode += 1 << bits;
 					} while (revcode < 512);
 				}
@@ -160,10 +156,11 @@ private void BuildTree(IList<byte> codeLengths)
 					subTree = -(subTree >> 4);
 					do
 					{
-						tree[subTree | (revcode >> 9)] = (short)((i << 4) | bits);
+						tree[subTree | (revcode >> 9)] = (short) ((i << 4) | bits);
 						revcode += 1 << bits;
 					} while (revcode < treeLen);
 				}
+
 				nextCode[bits] = code + (1 << (16 - bits));
 			}
 		}
diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs
index d8241c18c..b3a5a21be 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Runtime.CompilerServices;
 
 namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams
 {
@@ -36,12 +37,18 @@ public void Write(int value)
 		{
 			if (windowFilled++ == WindowSize)
 			{
-				throw new InvalidOperationException("Window full");
+				ThrowWindowFull();
 			}
 			window[windowEnd++] = (byte)value;
 			windowEnd &= WindowMask;
 		}
 
+		[MethodImpl(MethodImplOptions.NoInlining)]
+		private static void ThrowWindowFull()
+		{
+			throw new InvalidOperationException("Window full");
+		}
+
 		private void SlowRepeat(int repStart, int length, int distance)
 		{
 			while (length-- > 0)
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/InflaterHuffmanTreeTest.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/InflaterHuffmanTreeTest.cs
new file mode 100644
index 000000000..9a8553f1f
--- /dev/null
+++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/InflaterHuffmanTreeTest.cs
@@ -0,0 +1,51 @@
+using System;
+using NUnit.Framework;
+
+namespace ICSharpCode.SharpZipLib.Tests.Zip
+{
+	public class InflaterHuffmanTreeTest
+	{
+		/// <summary>
+		/// Generates code based on optimization described in https://github.com/dotnet/csharplang/issues/5295#issue-1028421234
+		/// </summary>
+		[Test]
+		[Explicit]
+		public void GenerateTrees()
+		{
+			// generates the byte arrays needed by InflaterHuffmanTree
+			var defLitLenTreeBytes = new byte[288];
+			int i = 0;
+			while (i < 144)
+			{
+				defLitLenTreeBytes[i++] = 8;
+			}
+
+			while (i < 256)
+			{
+				defLitLenTreeBytes[i++] = 9;
+			}
+
+			while (i < 280)
+			{
+				defLitLenTreeBytes[i++] = 7;
+			}
+
+			while (i < 288)
+			{
+				defLitLenTreeBytes[i++] = 8;
+			}
+
+			Console.WriteLine($"private static ReadOnlySpan<byte> defLitLenTreeBytes => new byte[] {{ { string.Join(", ",  defLitLenTreeBytes) } }};");
+
+
+			var defDistTreeBytes = new byte[32];
+			i = 0;
+			while (i < 32)
+			{
+				defDistTreeBytes[i++] = 5;
+			}
+
+			Console.WriteLine($"private static ReadOnlySpan<byte> defDistTreeBytes => new byte[] {{ { string.Join(", ",  defDistTreeBytes) } }};");
+		}
+	}
+}