glXMakeCurrent slowly leaks memory

Started by
7 comments, last by Bregma 7 years, 9 months ago

This is a very strange problem I've recently stumbled upon and for which I have no explanation nor remedy. The situation is the following:

Main thread is UI and Logic (toolkit has own Display connection).

Render thread is purely OpenGL (own context, own Display connection).

If I have one window rendering everything is fine and no memory leaks happen.

If I have two windows then during each render call each window is made current using glXMakeCurrent, rendered and later on swapped. So basically this each frame:

glXMakeCurrent(display, window1Context...)

render window1

glXMakeCurrent(display, window2Context...)

render window2

wait for data for next frame render

The interesting thing is that while everything runs fine the application slowly starts leaking memory. Not doing glXMakeCurrent the leaking goes away. Using glXMakeCurrent the leaking starts again. It's differently fast/slow on different computers.

Any idea what could be wrong there? OpenGL runs entirely in the thread. The main thread has no connection to OpenGL at all. It only has the UI toolkit so to speak. Also the render thread has an own Display connection which is thread-safe.

Ideas welcome since I'm out of ideas right now.

EDIT: Note. I tried only enabling glXMakeCurrent without rendering between the calls and the leaking is the same. So rendering is not the culprit.

Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

Advertisement

The first step is to take a dump and investigate what's actually going on.

Secondly,

Others reported some leaks using this method, so i'll want to know how you test the memory leak.

I've looked around a bit and can't find a straight answer.

Are there any resources that you aren't freeing up?

One way I test is using the process monitor to see if the overall applicatin memory stays stable or steadily increases. That showed the little run-away of memory due to glXMakeCurrent. Otherwise engine internal objects are ref-counted and stored in a global list if leak-checking is enabled. upon exiting it is checked if no such list contains objects still alive. So I can precisely tell no leaking goes on inside the internal workings. It happens really only if glXMakeCurrent is enabled even if nothing else is going on.

Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

You can also try:

* call glXMakeCurrent with the same context for a single window version (so call it for each frame for the same window) and see if leaks are still there

* change xorg version (to older and newer)

* change driver version (mainly if using nvidia drivers). In that case, use a stable driver, not a BETA one.

and see if things change. If you can find any difference and you're using the latest glx available version, report this accordingly.

glXMakeCurrent for the same window has no effect. So this one is not the problem. I went ahead and did a couple of tests.

valgrind on the editor. no leaks detected but memory jolts off in the process monitor. and with jolting off I mean like this:

Test System 1: around 10kb per second increase

Test System 2: around 100MB(!) per second increase.

so it can't be me leaking memory in my program. Valgrind would spot this. But why does the process memory consumption jolt off like this?

I also tested these situations:

for each frame

for each window

glXMakeCurrent()

// no render

for each window

glXSwapBuffers()

this leaks as mentioned above.

for each frame

for each window

glXMakeCurrent()

// no render

// no swapping

no leaking in this case

for each frame

// no glXMakeCurrent()

// no render

for each window

glXSwapBuffers()

no leaking in this case either.

So the leaking happens as soon as glXMakeCurrent is used together with glXSwapBuffers().And interestingly Valgrind does not pick up this nearly 1G of lost memory.

EDIT:

I did some more testing and it seems that on the Test System 1 with the slow rising memory consumption I had been a bit quick. Letting the editor sit fully loaded with all rendering going on kept memory consumption in process monitor at the same level across a couple of seconds. System 2 though does jolt off in the hundrets of MB.

Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

Hey, just out of interest. Are you working on a PC with an nVidia GPU? I remember having similar problems with an SFML application i wrote. When it was running in dual window mode it showed pretty much the same behaviour you were describing. But only on nVidia Cards. On my HD6850 it was running fine, as well as when using the integrated graphics.

Hey, just out of interest. Are you working on a PC with an nVidia GPU? I remember having similar problems with an SFML application i wrote. When it was running in dual window mode it showed pretty much the same behaviour you were describing. But only on nVidia Cards. On my HD6850 it was running fine, as well as when using the integrated graphics.

No, one system is a Radeon HD 7970 with Crimson driver while the other is some Radeon 5xxx (not sure right now) with AMDGPU driver. The running away happens on the AMDGPU one.

Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

It seems to be not a threading issue. Even with synchronous rendering it happens. Something is wrong in Mesa:

==00:00:22:15.628 4423== 544,154,936 bytes in 13,576,238 blocks are still reachable in loss record 68,955 of 68,955
==00:00:22:15.628 4423== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:22:15.628 4423== by 0x8A2714B: ??? (in /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0)
==00:00:22:15.628 4423== by 0x8A24ED0: ??? (in /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0)
==00:00:22:15.628 4423== by 0x8A26616: ??? (in /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0)
==00:00:22:15.628 4423== by 0x8A26720: xcb_wait_for_reply (in /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0)
==00:00:22:15.628 4423== by 0x84EE8C2: ??? (in /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0)
==00:00:22:15.628 4423== by 0x84E994E: ??? (in /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0)
==00:00:22:15.628 4423== by 0x84E3917: ??? (in /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0)
==00:00:22:15.628 4423== by 0x84E9E4B: ??? (in /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0)
==00:00:22:15.628 4423== by 0x84BD3B4: glXMakeContextCurrent (in /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0)

xcb_wait_for_reply shows up in all large scale leaking reports. Mesa bug?

Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

Could be a Mesa bug. Could be an XCB bug. You can probably install the debug symbols for both libraries to get a better idea.

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement