Qt6.5.1的应用程序,额外创建了40多个线程,多耗用200MB内存

Qt6.5.1的应用程序,额外创建了40多个线程,多耗用200MB内存。

初步判断,原因是开启了硬件加速的情况下,调用了NVIDIA的硬件加速接口,导致大量加载NVIDIA的接口dll,并连续创建了40多个线程。而不使用硬件加速的程序,则正常运行。NVIDIA的硬件加速接口调用,是因为QtWebEngine中集成了ffmpeg的视频解码,而ffmpeg中又集成了NVIDIA的Video SDK进行硬件解码。

本机刚好又安装了NVIDIA Video SDK,但排除此原因,不认为是编译时自动链接所致,因为编译时没有指定这个SDK路径。还是认为,此问题是qt 6.5.1带来的新问题,即Qt新版本开始默认支持NVIDIA的硬件解码,且优先使用。本人尝试通过禁止使用NVIDIA Video SDK,但无法编译通过,只能放弃。目前只能维持现状,或等待Qt官方修正,或等待NVIDIA官方修正。

尝试使用SoftGL模式,也出现了大量由opengl32sw.dll创建的多余线程。

 

2023.06.26:

Qt产生大量线程的问题。实在无法忍受大量的无效线程,不得不跟进一下。

Qt程序的系统线程,除了上面说的线程,还有Qt的WebEngineCore产生的几个工作线程和线程池。WebEngineCore的线程,除非不使用WebEngine,否则不好避免。好在内存消耗不多,线程也都是挂起状态,数量大约在15个。

 

而上述线程是从Qt 6.5版本开始出现的。本人拿同样的qt官方例子程序,使用Qt 6.4和Qt 6.5编译,最终情况也是类似,Qt 6.5编译的程序同样产生了大量线程。查阅官方的更新日志,找到了这个链接:Qt for Windows – Graphics Acceleration

内容如下:

 As of Qt 6, the default for Qt Quick on Windows is Direct3D 11. This is different from Qt 5, where the default was OpenGL, either directly, or through ANGLE, an OpenGL to Direct3D translator. ANGLE is no longer shipped with Qt in Qt 6.

 

这里说的是Quick程序,但我使用的是原生代码。所以,原生代码是否也是这样,就不得而知。于是,在文件 Qt\6.5.1\Src\qtbase\src\gui\rhi\qrhid3d11.cpp 中找到 D3D11CreateDevice 函数,断点,调试后发现,确实执行到了这里,而大量线程的创建,也正是在此函数内完成的。所以,推测关闭默认的Direct3D 11,应该就可以解决问题。但除了重新编译Qt时禁用之外,似乎没有其他好办法。但是,意外发现一个qrc文件qt-project.org\windows\openglblacklists\default.json,Qt会读取此文件,然后根据不同的cpu禁用不同的特性,以此解决gpu兼容问题。于是,我将此文件加入到了程序中,并且添加如下内容:

,
       {
          "id": 14,
          "description": "Disable DesktopGL on Windows with Mobile Intel(R) 4 Series Express Chipset Family graphics card (QTBUG-58772)",
          "os": {
              "type": "win"
          },
          "driver_version": {
            "op": "<=",
            "value": "98.17.12.6973"
          },
          "features": [
            "disable_d3d11"                //, "disable_desktopgl""disable_d3d9", "disable_angle", "disable_program_cache"
          ]
      }

这里去掉了厂商vendor_id和设备device_id的匹配,相当于直接对所有gpu,然后将driver_version的value改成一个超大的值,从而相当于间接起到禁用部分特性的功能。禁用后,线程还是很多,有NVIDIA的dll创建的线程,有opengl的dll创建的线程。

 

2023.06.27:

6.5的webengine模块默认启用了Angle,且在Windows 11使用D3D11。而6.4默认没有使用Angle。目前看,解决方法只能是回退到Qt 6.4,或保持现状。

 

转载请注明来源,谢谢。

有偿解决C++编程问题,承接项目定制开发;寻一份全职或兼职Windows C++开发工作。联系邮箱:[email protected]


老刀的技术日志 » Qt6.5.1的应用程序,额外创建了40多个线程,多耗用200MB内存

发表评论