Repository: godot
Issue: Vram 'leak': Not freeing all associated alllocations after null referencing textures (C#)
Labels: bug,topic:rendering,needs testing

### Godot version

4.1.1stable.mono

### System information

Godot v4.1.1.stable.mono - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2060 (NVIDIA; 31.0.15.3598) - AMD Ryzen 7 2700X Eight-Core Processor (16 Threads)

### Issue description

VRAM does not free completely after null referencing containing List<> as expected.

Texture memory frees as expected, but other allocated data remains in VRAM (see image)
![ex_1](https://github.com/godotengine/godot/assets/145625579/f8cd0625-b5e2-4f8e-811c-b4bdbbb22082)

Vram usage should return to 'Starting Vram Usage' level after textures are garbage collected.

Could be caching issue / failure to use cachemode parameter, as I use ```ResourceLoader.Load<Texture2D>(PATH,null, ResourceLoader.CacheMode.Ignore); ``` to load/unload textures twice in that image and it seems to establish a new baseline low Vram usage after textures are loaded the first time.

I verified that the Vram issue is limited to the application running environment, and does not cause a system level Vram leak once the application is closed (used GPU-Z to verify vram usage returns to pre application levels after closing)

### Steps to reproduce

Step 0: Download and install Godot 4.1.1 - .NET (latest version at time of writing) from: https://godotengine.org/download/windows/
Step 1: Download Attached Godot project to this post
Step 2: Open Project in newly installed Editor
Step 3: Run Game Application in Editor
Step 4: Switch Bottom Menu View in Editor to Debugger->Monitors
Step 5: Toggle the Monitors 'Video Mem' & 'Texture Mem' to track Vram and Texture usage over time
Step 6: Focus Running Game Application Window
Step 7: Push 'K' on keyboard to load textures into memory (Observe spike on monitors as expected)
Step 8:  Push 'L' on keyboard to unload textures from memory (Observe Tex Mem go down as expected, but Video Mem does not return to original level on monitors, forms new minimum low Vram usage that can't be freed by repeated calls to ```GC.Collect()```)

Below is the code for the only script running in the project (SYSTEM.cs):

```cs
using Godot;
using System;
using System.Collections.Generic;

public partial class SYSTEM : Node2D
{
	
	List<Texture2D> resourceTarget; // List<> that stores the references to the loaded Texture2D objects
	float d = 0.0f; // Used as a timer to repeatedly called GC.Collect() every second

	public override void _Ready()
	{	
		resourceTarget = new List<Texture2D>(); 
	}

	public override void _Process(double delta)
	{
		if(Input.IsActionJustPressed("debug_0")) // K Pressed
		{
			// load and add textures to List<>.
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0000.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0001.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0002.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0003.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0004.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0005.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0006.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0007.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0008.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0009.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0010.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0011.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0012.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0013.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0014.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0015.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0016.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0017.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0018.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0019.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0020.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0021.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0022.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0023.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0024.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0025.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0026.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0027.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0028.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0029.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0030.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0031.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0032.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0033.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0034.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0035.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0036.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0037.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0038.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0039.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0040.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0041.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0042.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0043.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0044.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0045.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0046.png",null, ResourceLoader.CacheMode.Ignore)); 
		resourceTarget.Add(ResourceLoader.Load<Texture2D>("res://Resources/test_anim_0000/img_0047.png",null, ResourceLoader.CacheMode.Ignore)); 
		}
		else if(Input.IsActionJustPressed("debug_1")) // L Pressed
		{	
			resourceTarget = null; // set reference to null, all associated vram usage with previously loaded textures should free, but only raw texture memory does
			GC.Collect(); //GC Call to attempt to clean any memory
		}

		// GC collect on a loop to show that repeated attempts to Garbage Collect have no effect on the VRAM usage after raw texture memory is collected
		d += (float)delta;

		if(d> 1.0f)
		{
			GC.Collect();
			d = 0.0f;
		}

	}
}

```

### Minimal reproduction project

[TEST.zip](https://github.com/godotengine/godot/files/12678902/TEST.zip)

EDIT: Added minimal repro using only gdscript scripts to demonstrate issue is not limited to C# as requested (see comment below relating to this)

[TEST_GDSCRIPT.zip](https://github.com/godotengine/godot/files/12679326/TEST_GDSCRIPT.zip)