Jump to content

Memory leak in Viewport::render


photo

Recommended Posts

I'm noticing a memory leak every time I make a call to several of the new Viewport::render* calls. These are the functions I've tested and experienced the issue with:

 

void render (Camera camera)

void renderImage2D (Camera camera, Image image)

void renderImage2D (Camera camera, Image image, int width, int height, int hdr = 0)

 

More details: My application creates a Unigine-Qt window (subclasses Unigine::App), then creates additional rendering windows to show other views (much like the old RenderQt sample which no longer appears to be part of 2.2.1). Each view is updated continuously during the run loop, so every time a paint event is requested, Viewport::render is called (once per additional window).

 

I've recreated the issue by porting the old RenderQt example to 2.2.1 (attached). I've narrowed the leak down to the single Viewport::render call -- with this line in, the program leaks, but when this line is commented, no memory is leaked. I'm building in release/x64/single precision on Windows. Am I forgetting something in order to prevent such leaking?

 

Even more details: In my program (which uses 6 external 1280x800 windows for rendering to projectors), the leak happens rapidly. I assume because I'm rendering fairly large textures (1280x800 x 6), Unigine quickly reaches 15-20+ GB of RAM, then crashes. What's strange is that I only notice this rapid leaking when the Unigine::App is minimized (perhaps because drawing happens faster when the the app is minimized, leading to more rapid Viewport::render calls?). However, in the attached example, I'm noticing leaking no matter if the main app is shown or minimized.

 

 

Thanks for your help!

 

Kevin

 

 

 

 

 

 

RenderQt-viewport.zip

Link to comment

Hi Kevin,

 

I assume, that you are using Windows, right? Unfortunately, it seems that some files are in binary format inside your archive. For example, RenderQt.pro can't be opened like project file inside QtCreator. The same thing happens with RenderQt.py - it's not a python script.

 

Could you please reupload these 2 files separately in different archive?

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Hi Kevin,

You are calling Unigine::Image::create() method every frame and not releasing the memory after it.

 

There are couple of ways to fix it:

  1. Call every frame src->grab(); at the end of your update() loop in RenderQt.h to clear the image resources.
  2. Create Image only ones in constructor (similar to Qimage image). In that case call of src->grab() is not required at all.

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Hi Silent,

 

Thanks for the quick response. I did as you suggested, and can confirm this stops the leak *while the app is in the foreground*. However, as soon as the main app is minimized, or goes to the background, the program continues to leak memory as before. This is the same issue I'm experiencing with our full program -- I've made sure to move all create() calls to the initialization, so I'm fairly certain this is a leak happening within the Viewport::render() commands and only happening when the app is minimized. Also, I'm using OpenGL -- I haven't tested using DX.

 

Furthermore, it's my understanding that grab() would only need to be used after a release() call, as I thought all pointers were set to be garbage collected automatically. Why is it the case that these ImagePtr's aren't getting garbage collected?

 

As always, thanks again for your help!

 

Kevin

Link to comment

Hi Kevin,

 

I was able to reduce the memory footprint by adding engine.app.setUpdate(1) into the world script (render.cpp) in init() section. Basically, we let the engine work in the background and do the garbage collection. We are still investigation what can cause such memory leak in the renderImage2D() method.

 

Furthermore, it's my understanding that grab() would only need to be used after a release() call, as I thought all pointers were set to be garbage collected automatically. Why is it the case that these ImagePtr's aren't getting garbage collected?

The problem is that our newly automatically generated API will return wrong pointer owner after calling Unigine::Image::create() method without arguments. I've already submitted ticket to our internal bug tracker regarding this issue.

 

Sorry for the inconvenience caused.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Understood, thanks. I can work easily around the Unigine::Image::create() issue, but the Viewport::render memory leak is causing significant issues for our development and production code (we will have to switch back to 2.0 until fixed). Please let me know once the issue is resolved, and if I can provide any additional info.

 

Thanks,

Kevin

Link to comment

Hi Kevin,

 

What can really help - is understanding of what task you are trying to achieve. Could you please describe the final result that you are expecting to see? Your sample is using outdated structure that not recommended to use in production anymore. Since 2.1.x we introduced new logic system and we recommend to switch to it instead. You can also easily create Qt project (with *.pro file) directly from SDK Browser where all required fils will be automatically created (WorldLogic / SystemLogic / EditorLogic).

 

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment
Hi Silent,

 

Our use case might be a little unique. We are using Unigine as a backend for a larger system rather than creating a game/simulations. The best way to demonstrate is to show one of our apps (see https://www.dropbox.com/s/u7r56vmtajqfnav/canvas.mp4?dl=0, temporary link). Unigine is being controlled by a remote computer (the video shows two PCs, one in top left that controls the experience, one in the bottom right that hosts unigine and renders to 6 external displays). All of our applications create geometry dynamically and add/replace textures constantly and/or play video. 

 

We just migrated to 2.2.1 and have looked in the new logic system briefly, although I don't know how well it will fit for our use case. We've written our own wrapper around the Unigine source to better handle our needs, and as far as I can tell, it will be difficult for us to structure our code in this way. The main point is that Unigine is a piece/library in our larger system, rather than controlling/running the entire program.

 

Kevin

Link to comment

Hi Kevin,

 

Thank you for the additional info and video. 

I've just created a new project via SDK Browser with C++ (Qmake) API and tried to reproduce the same issue, but without any success right now.

 

Could you please do the following and check if you have memory leak or not:

  • Create new project (Double x64 build) called unigine_project and select C++ (Qmake) project type.
  • Open folder with project;
  • Replace files in source and data directories with the files from attached zip archive;
  • Click Edit Code button and wait until QtCreator is started;
  • Click Build -> Run Qmake and Build -> Build Project "unigine_project";
  • After build is finished, press Run button (Ctrl + R).

 

Thanks!

 

unigine_project.zip

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment
  • 2 weeks later...

Hi Silent,

 

Thanks for the sample. I can confirm your testing: building in this way does not lead to a memory leak. Any idea what the differences are between my example and the one you provided? 

 

Thanks,

Kevin

Link to comment
×
×
  • Create New...