I've noticed memory leaks in my game - according to the Profiler, both Static and Dynamic memory continually increase until eventually crashing. Most of my code is in C#.
I've narrowed down at least the Dynamic leak to where I'm creating a ConcavePolygonShape and then calling SetFaces() on it with an array of vertices. If this is commented out, no Dynamic leak (although Static still climbs).
I've created a small test case to illustrate. Two scripts, one C# and one GDScript, both doing exactly the same thing, which is to create a new ConcavePolygonShape and populate via SetFaces() every call to _Process(). The GDScript version has flat Static memory and Object count and zero Dynamic, the C# version has Static and Dynamic memory and Object count all continually climbing. If I comment out the SetFaces() call in the C# version, Dynamic stays zero but Static and Object count still climb. If you increase the number of vertices, the leak gets larger faster (so seems proportional to number of vertices).
ConcavePolygonShape is not a Node but is held via a Reference as I understand, so should be ref-counted and disposed automatically once all references are gone (i.e. at the end of each _Process() call as I don't hold the ref anywhere).
What's going on? I'm leaning towards a leak bug in the C# godot stuff at the moment, but have I missed something obvious?
Seems very similar to Profiler Question, Memory leak C#?.
Scripts below, attach to a Spatial node in an empty project (switch between the GDScript and C# scripts to see the different behavior).
var collisionShapeFaces = ConcavePolygonShape.new()
var numVerts = 30
var vertices = 
for i in range(0, numVerts, 3):
vertices.append(Vector3(i, 0, 0))
vertices.append(Vector3(i, 1, 0))
vertices.append(Vector3(i, 0, 1))
public class ShapeLeak : Spatial
public override void _Ready()
public override void _Process(float delta)
Shape collisionShapeFaces = new ConcavePolygonShape();
int numVerts = 30;
Vector3 vertices = new Vector3[numVerts];
for (int i = 0; i < numVerts; i+=3)
vertices[i] = new Vector3(i, 0, 0);
vertices[i+1] = new Vector3(i, 1, 0);
vertices[i+2] = new Vector3(i, 0, 1);
// // SetFaces() is causing Dynamic Memory Leak, look in Debugger->Monitors Static & Dynamic memory
// // Try commenting out SetFaces() below to see the Dynamic then stay flat
// // Even with SetFaces() commented out, Static (& object count) steadily increases, in contrast
// // to the GDScript version of this script where Static and Object count stay flat and Dynamic is zero