godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.58k stars 21.27k forks source link

Memory leak in ResourceSaver when saving large scenes #67839

Open AlbuquerqueSenior opened 2 years ago

AlbuquerqueSenior commented 2 years ago

Godot version

4.0 beta3

System information

Linux KDE neon Vulkan - NVIDIA RTX 2060

Issue description

When using ResourceSaver.save() to generate large scenes, memory is being consumed until it reaches the limit.

Steps to reproduce

Run the block_generator.gd script inside the scripts/tools folder and wait for it to create the scenes in the prefab/scenario/render folder. Watch out for memory consumption when it generates 500-600 files (Approximately 5GB).

It seems to me that something is cached and not emptied.

Important notice: this script dynamically generates the scenario of my game, and it takes a few hours to complete the operation. In version 3.5 the same script worked without hitting the memory limit.

Thank you for your patience and understanding

Minimal reproduction project

resourcesaver_project.zip

AlbuquerqueSenior commented 2 years ago

I believe the error is on line 9529 of the block_generator.gd script

Calinou commented 2 years ago

I believe the error is on line 9529 of the block_generator.gd script

If your script has more than 9529 lines, it is probably not a minimal reproduction project :slightly_smiling_face:

Please trim down the project to only include what is strictly necessary, while making sure the bug can still be reproduced in the trimmed down version.

AlbuquerqueSenior commented 2 years ago

I'm sorry, but now I'm uploading a shortened version with just the code needed for testing.

Now this code generates equal scenario blocks, with 12mb each.

After generating 500 blocks you will notice that the memory consumption starts to rise slowly, and before finishing the work the memory reaches the limit of my notebook. resourcesaver_project.zip

AlbuquerqueSenior commented 2 years ago

The idea with this code is to generate scenario chunks that will be dynamically loaded and unloaded.

AlbuquerqueSenior commented 2 years ago

Looking through previous errors, I found a very similar error: https://github.com/godotengine/godot/issues/8225

AlbuquerqueSenior commented 2 years ago

I made a new test with the following code:

extends Node3D

var vertices var arr_mesh var arrays var m

func _process(delta): vertices = PackedVector3Array()

for i in range(5000):
    vertices.push_back(Vector3(0, 1 * i, 0))
    vertices.push_back(Vector3(1 * i, 0, 0))
    vertices.push_back(Vector3(0, 0, 1 * i))

# Initialize the ArrayMesh.
arr_mesh = ArrayMesh.new()
arrays = []
arrays.resize(Mesh.ARRAY_MAX)
arrays[Mesh.ARRAY_VERTEX] = vertices

# Create the Mesh.
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
m = MeshInstance3D.new()
m.mesh = arr_mesh

print(str(OS.get_static_memory_usage()))
krazyjakee commented 1 year ago

I'm trying to identify if this is the issue I'm facing. When you say memory is being consumed until it reaches the limit what symptom do you then see? For me, entire application task disappears from task manager with no error. Would that be consistent?