-
Notifications
You must be signed in to change notification settings - Fork 480
Open
Labels
Description
Describe the issue
Description:
I’m seeing a steadily increasing memory footprint when running BlenderProc in a loop to generate many scenes. Even though I call bproc.clean_up(True) (and force a Python gc.collect()), RAM usage, GPU memory and the time spent inside bproc.clean_up() grow with each iteration until the script ultimately crashes. I suspect that some internal data (Cycles render buffers) is never freed.
Expected Behavior:
- Memory usage should remain roughly constant after each iteration (aside from small fluctuations).
- bproc.clean_up(True) should consistently take a small, bounded amount of time (< 0.1 s).
Actual Behavior:
- The RSS steadily increases by ~5–20 MB per iteration.
- bproc.clean_up(True) time grows linearly until it dominates the iteration time.
- The script eventually aborts due to out‐of‐memory or unacceptable slowdown.
Minimal code example
import blenderproc as bproc
import bpy
import os
import numpy as np
import random
import pandas as pd
import tqdm
# Nach dem Rendering
import gc
import time
import psutil
# import debugpy
# debugpy.listen(5678)
# debugpy.wait_for_client()
# Sammeln Sie alle Metriken in einer Liste
metrics_list = []
def log_performance_metrics(iteration, comment, output_dir):
process = psutil.Process(os.getpid())
mi = process.memory_info().rss / 1024 / 1024
objs = len(bpy.data.objects)
meshes = len(bpy.data.meshes)
now = time.time()
if hasattr(log_performance_metrics, "last"):
it = now - log_performance_metrics.last
else:
it = 0.0
log_performance_metrics.last = now
metrics_list.append(
{
"comment": comment,
"iteration": iteration,
"memory_usage_mb": round(mi, 2),
"blender_objects": objs,
"blender_meshes": meshes,
"timestamp": round(now, 2),
"iteration_time": round(it, 2),
"bpy.data.meshes": len(bpy.data.meshes),
"bpy.data.objects": len(bpy.data.objects),
"bpy.data.images": len(bpy.data.images),
"bpy.data.materials": len(bpy.data.materials),
"bpy.data.textures": len(bpy.data.textures),
"Node Groups": len(bpy.data.node_groups),
}
)
# Am Ende des Skripts (oder nach x Schleifen) einmal schreiben:
df = pd.DataFrame(metrics_list)
df.to_csv(
os.path.join(output_dir, "performance_log.csv"),
sep=";",
decimal=",", # Komma als Dezimaltrenner
index=False,
)
return metrics_list[-1]
if __name__ == "__main__":
output_dir_path = r"D:\output"
os.makedirs(output_dir_path, exist_ok=True)
n_scenes = 2000
bproc.init()
bproc.renderer.enable_depth_output(
activate_antialiasing=False, output_dir=None, output_key="depth"
)
resolutions_render = [
(1920, 1080),
(1600, 1200),
(1280, 960),
(1280, 720),
(1024, 1024),
(640, 480),
]
start_index = 0
for iteration in tqdm.tqdm(range(n_scenes)):
iter_start_time = time.time()
start_metrics = log_performance_metrics(iteration, "0.)", output_dir_path)
print(
f"0.) Iteration {iteration}: Memory: {end_metrics['memory_usage_mb']:.2f} MB, Objects: {end_metrics['blender_objects']}, Time: {time.time() - iter_start_time:.2f}s"
)
resolution_render = random.choice(resolutions_render)
bproc.clean_up(True)
gc.collect()
end_metrics = log_performance_metrics(iteration, "1.)", output_dir_path)
print(
f"1.) Iteration {iteration}: Memory: {end_metrics['memory_usage_mb']:.2f} MB, Objects: {end_metrics['blender_objects']}, Time: {time.time() - iter_start_time:.2f}s"
)
bproc.camera.set_resolution(resolution_render[0], resolution_render[1])
bproc.utility.reset_keyframes()
light = bproc.types.Light()
light.set_location([0, 2, 4])
light.set_energy(np.random.uniform(400, 500))
poi = [0, 0, 0]
location_cam = np.array([0, 0, 1])
print("location_cam", location_cam)
rotation_matrix = bproc.camera.rotation_from_forward_vec(
poi - location_cam, inplane_rot=np.random.uniform(-0.7854, 0.7854)
)
cam2world_matrix = bproc.math.build_transformation_mat(
location_cam, rotation_matrix
)
bproc.camera.add_camera_pose(cam2world_matrix)
end_metrics = log_performance_metrics(iteration, "2.)", output_dir_path)
print(
f"2.) Iteration {iteration}: Memory: {end_metrics['memory_usage_mb']:.2f} MB, Objects: {end_metrics['blender_objects']}, Time: {time.time() - iter_start_time:.2f}s"
)
bproc.object.create_primitive("MONKEY", scale=[0.5, 0.5, 0.5])
end_metrics = log_performance_metrics(iteration, "3.)", output_dir_path)
print(
f"3.) Iteration {iteration}: Memory: {end_metrics['memory_usage_mb']:.2f} MB, Objects: {end_metrics['blender_objects']}, Time: {time.time() - iter_start_time:.2f}s"
)
bproc.renderer.enable_segmentation_output(
map_by="category_id", default_values={"category_id": 2}
)
bproc.renderer.set_output_format(enable_transparency=True)
end_metrics = log_performance_metrics(iteration, "4.)", output_dir_path)
print(
f"4.) Iteration {iteration}: Memory: {end_metrics['memory_usage_mb']:.2f} MB, Objects: {end_metrics['blender_objects']}, Time: {time.time() - iter_start_time:.2f}s"
)
data = bproc.renderer.render()
tree = bpy.context.scene.node_tree
tree.nodes.remove(
tree.nodes[-1]
) # ich muss das machen, weil enable_segmentation_output immer neue nodes erstellt.
tree.nodes.remove(tree.nodes[-1])
end_metrics = log_performance_metrics(iteration, "5.)", output_dir_path)
print(
f"5.) Iteration {iteration}: Memory: {end_metrics['memory_usage_mb']:.2f} MB, Objects: {end_metrics['blender_objects']}, Time: {time.time() - iter_start_time:.2f}s"
)
Files required to run the code
No response
Expected behavior
- Memory usage should remain roughly constant after each iteration (aside from small fluctuations).
- bproc.clean_up(True) should consistently take a small, bounded amount of time (< 0.1 s).
BlenderProc version
BlenderProc 2.8.0