Memory Leak in vtkRenderWindow Render

I am encountering what appears to be a memory leak when calling Render in a loop for a vtkRenderWindow. See the code below for a minimal example. The size of the leak varies depending on the PC, anywhere from 1 MB to 10 MB per 3000 iterations. I have tested it on 3 different PCs. When I comment out the Render line (“renwin->Render();”) there is no memory leak.

Any help would be greatly appreciated!

// vtk
#include <vtkImageActor.h>
#include <vtkImageData.h>
#include <vtkImageMapper3D.h>
#include <vtkImageMapToColors.h>
#include <vtkLookupTable.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>

// stl
#include <iostream>
#include <thread>

// main
int main(int argc, char* argv[])
{
	// vtk pipeline
	vtkSmartPointer<vtkImageData> im = vtkSmartPointer<vtkImageData>::New();
	im->SetDimensions(600, 300, 1);
	im->AllocateScalars(VTK_UNSIGNED_SHORT, 1);
	unsigned short* raw = static_cast<unsigned short*>(im->GetScalarPointer());
	memset(raw, 0, 600 * 300 * 2);

	vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
	lut->SetRange(0, 255);

	vtkSmartPointer<vtkImageMapToColors> mapper = vtkSmartPointer<vtkImageMapToColors>::New();
	mapper->SetLookupTable(lut);
	mapper->SetInputData(im);
	mapper->Update();

	vtkSmartPointer<vtkImageActor> actor = vtkSmartPointer<vtkImageActor>::New();
	actor->GetMapper()->SetInputConnection(mapper->GetOutputPort());

	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(actor);

	vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
	renwin->AddRenderer(renderer);
	renwin->SetSize(600, 600);

	vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	interactor->SetRenderWindow(renwin);

	renwin->Render();
	interactor->Initialize();

	// loop through iterations
	for (int i = 0; i < 100000; ++i)
	{
		std::cout << i << "\n";

		// update image
		const int val = 24 * (i % 10);
		for (int j = 0; j < 600 * 200; ++j)
			raw[j] = val;

		// render
		im->Modified();
		mapper->Modified();

		renwin->Render();

		// sleep
		std::this_thread::sleep_for(std::chrono::milliseconds(20));
	}

	interactor->Start();

    return 0;
}

System info:

  • Windows 11 Pro
  • CPU: Intel i7
  • GPU: Nvidia RTX A2000
  • 16 GB RAM
  • VTK 9.4.1
  • Visual Studio 2019

Hello,

Did you find the leak by profiling/debugging or by just looking at total RAM allocated? I ask this because the later is not a reliable way to tell whether a program has an actual memory leak as modern OSes and virtual machines often have fancy memory management. The Render() function calls a lot of stuff under the hood, including the OpenGL backend and GUI API (e.g. Qt). Of course, high RAM usage may be a symptom of allocation issues, but once a suspicion is raised, one must investigate further to arrive at a conclusion.

best,

PC

I’ve used both. In task manager or process explorer, RAM usage continually increases until the system runs out of memory completely if I run it with sufficient iterations. And I’ve also confirmed the memory leak using tools like the Visual Studio memory profiler, MTuner, and a few others.

Edit: This appears to only be a small part of the leak…
Some info from the Visual Studio profiler below. It looks like it’s happening in vtkTimerLog. My guess is the Renderer creates a timer log with text entries (e.g. “OpenGL Dev Render…”), but doesn’t cleanup this text data.

Hello,

This code is very unsafe:

    unsigned short* raw = static_cast<unsigned short*>(im->GetScalarPointer());
	memset(raw, 0, 600 * 300 * 2);

If I were the code reviewer, I’d reject it on sight. :upside_down_face:

You’re basically setting something in VTK’s bowels via a very risky low level C-style call. Please, try to set your data values via VTK API and try again.

best,

PC

Some more info: I’ve tracked down most of the memory leak to line 190 in “vtkOpenGLVertexArrayObject.cxx” where it calls the OpenGL function “glBindVertexArray(0);” in the Release function.

That line appears to add about 1 MB to the heap once every few seconds while running the Render loop. I have no idea why, or what can be done to fix it. Any help would be appreciated!

@Paulo_Carvalho : Even if I comment out that code and never change the values of the image, the memory leak still happens.

That sounds like an issue with the opengl graphics driver.

Thanks, is there anything I can do to attempt to address this? I am using the latest driver from Nvidia (572.60).

I think the driver is caching the VAO in its implementation until the next usage. Nothing to worry about here. This is not really a memory leak because it may be clearing the cache when your application exits. The OpenGL driver is just not accustomed to this usage pattern of binding 0 since the spec says it’s not really required to bind 0 to a vertex array.

If the memory growth is really bothering you, you could try creating a new mapper per iteration of the loop and assign it to your actor.

Replacing the mapper doesn’t appear to make a difference.

Our application produces high framerate video and needs to be on for long periods of time uninterrupted, so we can’t rely on application exit to clear out the memory. The high video framerate combined with this memory leak eventually leads to the application running out of memory.

Is there perhaps a way for me to periodically request VTK to clear out any unused VAO in opengl? Or another workaround?

Perhaps offscreen rendering may suit your need: https://examples.vtk.org/site/Cxx/Utilities/OffScreenRendering/

Unfortunately the video must always be visible, like a CCTV.

Maybe taking a look at the Animation example (https://examples.vtk.org/site/Cxx/Utilities/Animation/) will cast a light on how to properly code that. You’re essentially trying to make an animation.

I believe I’ve identified the ultimate culprit: the Nvidia driver. It turns out that downgrading the driver to an older version, specifically 553.35 (from November 2024) fixes the issue. For now we can use the older driver, but this leaves us in a tricky situation as we likely won’t be able to use an older driver for long. Maybe VTK support for WebGPU will be available soon…

good to know downgrading the driver fixed the issue.

Maybe you could report the issue to them so you can have it fixed in a later version.

Yes, I’ve done so in the hopes of that.

Perhaps you could make a branch where you code your application following the pattern of the Animation example above. It is possible that you circumvent the driver bug in case you can’t afford the time waiting for NVidia to come up with a hot fix.

The issue is not fixed by using a setup like in the animation example (timer callback).