为什么QML Image占用这么多内存?减慢应用

时间:2019-08-07 19:22:46

标签: javascript qt qml qtquick2 qtquickcontrols2

当我加载图像时,我的Qt Quick应用程序正在减慢速度并消耗过多的内存。我正在加载大约5张大的PNG图片,每张大约50MB。

在此处查看尺寸:

enter image description here

在加载图像之前,应用程序的内存消耗约为300MB,还不错...然后,当我加载5张图像时,它会跳至4.4 GB并停留在那里! (我尝试在完成时调用gc(),但没有执行任何操作)

所以我做了一些实验。我写了这个基本应用程序,只是一个QML图像。我执行时没有图像源,内存为28.7 MB

import QtQuick 2.12
import QtQuick.Controls 2.3

Image {
    id: imageId
    anchors.fill: parent
    fillMode: Image.PreserveAspectFit
    anchors.centerIn: parent
    //source: 'test_images/1.png'
}

这是Mac的“活动监视器”的屏幕截图

enter image description here

当我添加50MB图像作为源时,内存消耗跃升至1.39GB并停留在那里!即使在gc()之后什么也没做...

import QtQuick 2.12
import QtQuick.Controls 2.3

Image {
    id: imageId
    anchors.fill: parent
    fillMode: Image.PreserveAspectFit
    anchors.centerIn: parent
    source: 'test_images/1.png'
}

“活动监视器”中的另一个屏幕截图

enter image description here

此Image对象发生了什么事情,使其消耗了1.39GB的内存!图像只有50MB!这是我的应用程序出现问题的根源,这使我的应用程序几乎无法使用。这是QtQuick平台的主要问题。

有关如何解决此问题的任何评论或建议?谢谢!我正在使用Qt 5.12

2 个答案:

答案 0 :(得分:3)

PNG文件的大小与运行时的RAM使用率无关。 存储为PNG的图像会被压缩,因此尺寸可能非常小。

当您在程序中加载并显示PNG图像时,该图像将被解压缩并使用更多的内存。

通常对于具有4个通道(RGBA),每个通道8位的图像,内存占用量将为:

memory = 1 byte * 4 channels * width * height
  • 对于1920x1080的图像,它将提供8,100 KiB。
  • 对于4K图像:32,400 KiB
  • 对于11,000x11,000的图片: 462 MiB

因此,加载多个11,000x11,000张图像的程序占用几GB RAM并不奇怪。

对于单个图像,报告的1.39 GB的消耗仍然令人惊讶。但是有几种可能的解释:

  • Qt(和OpenGL)需要制作和存储图像副本​​。
  • 您的PNG每个通道使用8位以上。我认为PNG每个通道最多可以增加16位。如果是您的情况,它将使RAM消耗翻倍。
  • 图像存储具有存储大图像的内存开销,从而增加了内存消耗。
  • 某处有一个错误...

有减少内存占用的可能解决方案,但我认为它们都需要减小图像大小。鉴于大多数屏幕为4K或更小,因此您无需在给定时间显示所有图像像素。因此,您可以做的就是裁剪图像或调整图像的大小以适合您的实际需求。此操作可以静态(即在编译之前自行完成),也可以在运行时动态完成:加载图像,计算缩小后的图像并卸载原始图像。

答案 1 :(得分:0)

您可以尝试使用此QML图片属性来尝试调整图片大小

 sourceSize.height:height
 sourceSize.width: width

https://doc.qt.io/qt-5/qml-qtquick-image.html#sourceSize-prop