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

Why is QML Image taking up so much memory? Slowing down application

当我加载图像时,我的 Qt Quick 应用程序速度变慢并且占用了太多内存。我正在加载大约 5 张 PNG 图片,每张图片大约 50MB。

在这里查看尺码:

在加载图像之前,应用程序的内存消耗约为 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 的 'Activity Monitor'

的屏幕截图

当我添加 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'
}

来自 'Activity Monitor'

的另一个屏幕截图

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

对如何解决这个问题有什么意见或建议吗?谢谢!我正在使用 Qt 5.12

PNG 文件大小与运行时的 RAM 使用量无关。 以 PNG 格式存储的图像经过压缩,因此可以具有非常小的尺寸。

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

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

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 或更小,您永远不需要在给定时间显示所有图像像素。所以你可以做的是根据你的需要裁剪或调整图像的大小。这可以静态完成(即您在编译之前自己完成),或在运行时动态完成:您加载图像,计算缩小图像并卸载原始图像。

您可以试试这个 QML 图像属性来尝试调整图像大小

 sourceSize.height:height
 sourceSize.width: width

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