【问题标题】:Releasing unneeded QImages释放不需要的 QImages
【发布时间】:2013-02-13 03:53:23
【问题描述】:

我的应用程序将网络摄像头图像流式传输到QWidget,然后在显示这些图像后就不再需要这些图像。应用程序运行了大约一两分钟,然后出现数十次此错误并崩溃:

QImage: out of memory, returning null image

QWidget 使用 displayImage(QImage) 方法,该方法每秒被调用多次。我觉得图像应该将指针作为参数,但我没有理由支持它。

如何确保QImages 从内存中释放?

注意:为了创建图像,我使用了 SO question how to convert an opencv cv::Mat to qimage 的已接受答案中描述的技术。

【问题讨论】:

  • 我不知道 Qt,所以这可能无关紧要,但是你是如何创建 QImage 的?
  • 我已经更新了我的答案。基本上,该应用程序使用 OpenCV 进行捕获,然后将 cv::Mat 转换为 QImage 以进行显示。
  • QImage 使用隐式共享,因此使用指针不会有任何好处。

标签: c++ qt memory


【解决方案1】:

QImage 类使用隐式数据共享。摘自doc

Qt 中的许多 C++ 类使用隐式数据共享来最大化资源 使用并尽量减少复制。隐式共享类都是安全的 作为参数传递时高效,因为只有一个指向 数据被传递,并且只有当一个 函数写入它,即写时复制。

共享类由指向共享数据块的指针组成 包含引用计数和数据。

创建共享对象时,它会将引用计数设置为 1。 每当有新对象引用 共享数据,并在对象取消引用共享数据时递减 数据。当引用计数变为时删除共享数据 零。

隐式共享发生在幕后;程序员做 不用担心。

这意味着如果您将 QImage 对象按值传递给 displayImage() ,则将创建一个新的 QImage ,但不会复制第一个 QImage 中的图像数据,而只会增加一个共享引用计数器。但这也意味着,如果您想释放您分配的第一个 QImage 对象的内存,那么您需要确保两个 QImage 对象都超出范围。

【讨论】:

    【解决方案2】:

    docs 中提到的关于隐式共享:

    创建共享对象时,它会将引用计数设置为 1。 每当有新对象引用 共享数据,并在对象取消引用共享数据时递减 数据。当引用计数变为时删除共享数据 零。

    这意味着您必须在代码中的某处引用 QImage 帧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-18
      • 2012-02-23
      • 2014-02-18
      • 2017-03-02
      • 1970-01-01
      • 2010-09-24
      • 2016-09-05
      • 1970-01-01
      相关资源
      最近更新 更多