【问题标题】:QImage out of memoryQImage内存不足
【发布时间】:2014-02-21 14:53:54
【问题描述】:

我对 QGLWidget 进行了子分类,并在其中显示了一个图像。

对于小图像(比如 1200*1000),它可以正常工作。

对于较大的 (10000 * 6000),它会崩溃。

MyGLWidget::MyGLWidget(QImage* image, QWidget *parent) : QGLWidget(parent)
{
    // ...
    _data = *image;
    _gldata = QGLWidget::convertToGLFormat(_data); // Crash at this point.
    // ...
}

错误:

QImage: out of memory, returning null image
ASSERT: "dst.depth() == 32" in file qgl.cpp, line 2094

我有 8GB 的​​内存,应用程序占用最大内存。 1GB。

我能做什么?

编辑

好的,假设我的 RAM 用完了,我该如何发现这个错误?

try
{
    _gldata = QGLWidget::convertToGLFormat(_data);
}
catch(...)
{
    qDebug() << "e.what()";
}

看起来也不例外。

【问题讨论】:

  • 这不是出自 vram 而非 ram 吗?
  • @paulm 我不知道。我怎么知道?
  • 调用convert方法前_data.isNull()是真还是假?
  • 您正在制作 x86 或 x64 应用程序?
  • 使用 GPU-Z 之类的东西来检查 GPU 内存负载

标签: c++ qt opengl memory


【解决方案1】:

你的内存用完了。

而且我什至不确定 QImage 是否可以处理如此大的图像。

converToGLFormat 不会在 GPU 上分配任何东西,它只是将图像转换为 ARGB8888 格式并使用正确的字节顺序,即使其适合通过glTex(Sub)Image2D 上传,请参阅here。在 Qt 5.2 中,如果您正在处理纹理,您还可以考虑使用 QOpenGLTexture,如果有正确的 GPU 功能,它可以让您避免此转换步骤。

【讨论】:

  • 我不认为我的内存不足。另外,QImage 可以处理那么大的图像,当我不显示任何内容时它可以工作,只需保存它。
  • 您在 2GB 或 3GB 的可寻址空间中要求 240MB (10k*6k*4Bpp) 的连续内存(您在 x86 下;2 或 3 取决于 Windows / Linux)。你真的相信这不是内存不足的情况吗?
  • 如果您仍然不相信 libc 为 malloc 返回 NULL(这意味着您的内存不足),然后在调试器中运行您的程序,并将 QT_FATAL_WARNINGS env 变量设置为 1 . 它会让你的程序在 QImage 警告时崩溃。看看之前的线条,它们应该涉及到一个新图像的创建。在那里放一个断点,重新运行你的程序,看看为什么 Qt 不能分配图像。
  • 我已经按照您的要求进行了调试。它崩溃了,并显示以下消息:QImage:内存不足,返回空图像。有什么办法,捕捉到这个,我不知道这是什么(不是例外)。
  • 您是否也做了我要求的所有事情?在调试器中运行并遍历 Qt 的代码?
【解决方案2】:

convertToGLFormat 中没有真正的错误处理,如果您的 RAM 不足或图像格式不正确,它只会在 Q_ASSERT 崩溃。

作为一种解决方法,您可以尝试分配与convertToGLFormat 相同大小的图像,如果成功,则释放图像并调用该函数,因为它也可能会成功,如果没有,则跳过该图像。

QImage dummy(_data.size(), QImage::Format_ARGB32);
if (!dummy.isNull()) {
    dummy = QImage(); // free the image
    _gldata = QGLWidget::convertToGLFormat(_data);
}

【讨论】:

  • 实际上,它不处理OOM是一个也许的错误。 QImage 本身有一些检查。相反,该代码不检查分配失败。但无论如何:Qt 假设您永远不会耗尽内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
相关资源
最近更新 更多