为啥 QML Image 占用这么多内存?减慢申请
Posted
技术标签:
【中文标题】为啥 QML Image 占用这么多内存?减慢申请【英文标题】:Why is QML Image taking up so much memory? Slowing down application为什么 QML Image 占用这么多内存?减慢申请 【发布时间】:2019-08-07 19:22:46 【问题描述】:当我加载图像时,我的 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 的“活动监视器”的屏幕截图
当我添加 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'
“活动监视器”的另一个屏幕截图
这个 Image 对象发生了什么,使它消耗了 1.39GB 的内存!图片只有50MB!这是我的应用程序问题的根源,它使我的应用程序几乎无法使用。这是 QtQuick 平台的一个主要问题。
有关如何解决此问题的任何 cmets 或建议?谢谢!我正在使用 Qt 5.12
【问题讨论】:
图片的像素大小是多少? 就我而言,我从未见过在 Windows 和 Linux 上如此糟糕的消耗。通常它可能需要 200% 的图像大小、好的缓存等。不幸的是我无法在 Mac 中测试它。无论如何,如果你只想显示图像,我的意思是没有效果等,你可以编写你的自定义项目,它只是在画布上绘制图像而不是其他任何东西。 @BenjaminT 像素大小为 11,000 x 11,000 【参考方案1】: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 或更小,您永远不需要在给定时间显示所有图像像素。因此,您可以做的是将图像裁剪或调整为您真正需要的大小。这可以静态完成(即在编译之前您自己完成),也可以在运行时动态完成:加载图像、计算缩小图像并卸载原始图像。
【讨论】:
【参考方案2】:你可以试试这个 QML 图像属性来尝试调整图像大小
sourceSize.height:height
sourceSize.width: width
https://doc.qt.io/qt-5/qml-qtquick-image.html#sourceSize-prop
【讨论】:
另外,您可以在加载之前使用 QQuickImageProvider 在 C++ 中调整图像大小以上是关于为啥 QML Image 占用这么多内存?减慢申请的主要内容,如果未能解决你的问题,请参考以下文章