diff --git a/CHANGELOG.md b/CHANGELOG.md
index b2e731d7..6bfc474e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,7 +18,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Changed `reg`, `area` arrays to byte arrays for uniformity and efficiency in `DtTileCacheContour`
 - Changed `RcChunkyTriMesh` to separate the function and variable.
 - Changed to consolidate vector-related functions into one place.
-- Changed stack handling from List to a fixed-size array with manual index management for optimization in `RcLayers.BuildHeightfieldLayers`
+- Changed stack handling from List to a fixed-size array with manual index management for optimization in `RcLayers.BuildHeightfieldLayers()`
+- Changed to use Span<byte> and stackalloc for improved performance and memory management in `RcLayers.BuildHeightfieldLayers()`
 
 ### Removed
 - Removed RcMeshDetails.VdistSq2(float[], float[])
diff --git a/src/DotRecast.Recast/RcLayers.cs b/src/DotRecast.Recast/RcLayers.cs
index 4a2c5790..df35834b 100644
--- a/src/DotRecast.Recast/RcLayers.cs
+++ b/src/DotRecast.Recast/RcLayers.cs
@@ -25,7 +25,6 @@ 3. This notice may not be removed or altered from any source distribution.
 
 namespace DotRecast.Recast
 {
-    
     using static RcRecast;
 
     public static class RcLayers
@@ -61,7 +60,6 @@ private static bool OverlapRange(int amin, int amax, int bmin, int bmax)
         /// @name Layer, Contour, Polymesh, and Detail Mesh Functions
         /// @see rcHeightfieldLayer, rcContourSet, rcPolyMesh, rcPolyMeshDetail
         /// @{
-
         /// Builds a layer set from the specified compact heightfield.
         /// @ingroup recast
         /// @param[in,out]	ctx				The build context to use during the operation.
@@ -79,10 +77,10 @@ public static bool BuildHeightfieldLayers(RcContext ctx, RcCompactHeightfield ch
 
             int w = chf.width;
             int h = chf.height;
-            
-            byte[] srcReg = new byte[chf.spanCount];
-            Array.Fill(srcReg, (byte)0xFF);
-            
+
+            Span<byte> srcReg = stackalloc byte[chf.spanCount];
+            srcReg.Fill(0xFF);
+
             int nsweeps = chf.width;
             RcLayerSweepSpan[] sweeps = new RcLayerSweepSpan[nsweeps];
             for (int i = 0; i < sweeps.Length; i++)
@@ -91,14 +89,14 @@ public static bool BuildHeightfieldLayers(RcContext ctx, RcCompactHeightfield ch
             }
 
             // Partition walkable area into monotone regions.
-            int[] prevCount = new int[256];
+            Span<int> prevCount = stackalloc int[256];
             byte regId = 0;
-            
+
             // Sweep one line at a time.
             for (int y = borderSize; y < h - borderSize; ++y)
             {
                 // Collect spans from this row.
-                Array.Fill(prevCount, 0);
+                prevCount.Fill(0);
                 byte sweepId = 0;
 
                 for (int x = borderSize; x < w - borderSize; ++x)
@@ -110,9 +108,9 @@ public static bool BuildHeightfieldLayers(RcContext ctx, RcCompactHeightfield ch
                         ref RcCompactSpan s = ref chf.spans[i];
                         if (chf.areas[i] == RC_NULL_AREA)
                             continue;
-                        
+
                         byte sid = 0xFF;
-                        
+
                         // -x
                         if (GetCon(ref s, 0) != RC_NOT_CONNECTED)
                         {
@@ -292,7 +290,7 @@ public static bool BuildHeightfieldLayers(RcContext ctx, RcCompactHeightfield ch
                     RcLayerRegion reg = regs[stack[0]];
                     nstack--;
                     for (int j = 0; j < nstack; ++j)
-                        stack[j] = stack[j+1];
+                        stack[j] = stack[j + 1];
 
                     foreach (int nei in reg.neis)
                     {
@@ -457,7 +455,7 @@ public static bool BuildHeightfieldLayers(RcContext ctx, RcCompactHeightfield ch
             bmin.Z += borderSize * chf.cs;
             bmax.X -= borderSize * chf.cs;
             bmax.Z -= borderSize * chf.cs;
-            
+
             lset = new RcHeightfieldLayerSet();
             lset.layers = new RcHeightfieldLayer[layerId];
             for (int i = 0; i < lset.layers.Length; i++)