为什么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
当我加载图像时,我的 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