Qt平台下C++内存管理

2023-11-02

分享我在编程中的设计观念,遇到的技术点,让我们在工作和生活中一起追求自由

这几年,自由的概念让我印象深刻,前不久看到一个词叫辞职自由。

对,我刚刚辞职。站在新公司小山丘前,我想别人在实现财务自由的时候,我在追求加班自由,加班时努力搬砖,同时也有不加班的自由,架构让我们自由。

01 编程碎念

我的编程观念,是在公司砖海中,受导师和大咖影响逐步形成。文中观点均来源于真实的技术实践,部分理念也是继承前人的设计成果,如有侵犯的地方请告知。在此特别感谢给予我点拨的人,站在大咖的肩膀上,让我们看得更远。

文中提到的编程观念,大部分是基于C++实现的基础技术,有Qt框架相关的,也有设计模式、面向对象相关的。可能大家会想,现在都是AI云的时代了,这些太老了。但我认为,这些才是编程的基础,这就是正确的编程世界观。

02 内存管理

某日,我在调试bug的时候,发现Qt源码中已经少有“*”形式的指针了。回想公司的代码,大多写于2010年,满满的*星,我闭了一下眼睛,感觉到熟悉的腐败味道。

2019年接手一个项目,一个反复无常近乎夭折的项目。在此之前,已经有同事在里面挣扎了几月,眼看要发布版本了,压力测试却不能运行3时。

C++编程中,内存一直就是显著的问题。在Qt平台中,我推荐使用Qt智能指针、对象树、大内存技术来进行内存管理。

03智能指针

智能指针是内存管理的工具,在语法层次上,为C++工程师降低了内存管理难度,能有效预防不经意笔误导致的内存泄漏,并减少了内存管理代码量。

范围指针QScopedPointer

QScopedPointer p(new MyClass ());

Scope为“范围”的意思。可以理解为,QScopedPointer对象p管理的内存,在p生命周期内有效。

这是一个在项目中经常使用的智能指针,经常使用的场景:
1、类的成员指针

class MyPrivateClass; 
class MyClass
{
  private:
      QScopedPointer<MyPrivateClass> privatePtr; 
  public:
      MyClass(); 
      inline ~MyClass() {} 
};

注意事项:
QScopedPointer禁止与QObject对象树中的对象组合使用,对象树中parent释放的时候,会释放其子节点,QScopedPointer对象再次释放child内存时,会导致错误。

对象追踪指针QPointer

QPointer label = new QLabel(parent);

针对QObject的追踪指针,QPointer并不会释放目标对象,用意在于记录QObject,以便在其他成员函数中使用。

QPointer就像一个GPS定位器,在目标对象被释放后,自动置为0,即parent析构时析构子对象QLabel,此后label记录的内存为0。
需要注意管理的目标对象必须从QObject派生。

这是一个在项目中经常使用的智能指针,经常使用的场景:
1、 QObject子对象,作为成员指针时
2、 记录非自身管理的QObject对象指针时

共享指针QSharedPointer和QWeakPointer

QSharedPointer p(new MyClass ());

共享指针,意为多个QSharedPointer共享同个内存对象。当p自身被释放时,会判断自身管理的内存对象,是否有被其他的QSharedPointer引用共享,如果没有则释放管理的内存对象。

经常使用的场景:
1、类的成员指针,特别是容器类型中使用,减少了对容器内存对象的释放操作,容器的增删操作,QSharedPointer保证其管理的内存被释放。

注意事项:
将QSharedPointer管理的对象指针A,注册到其他需要管理A生命周期的类中,会发生错误。

比如postEvent的QEvent对象使用QSharedPointer管理的话,QSharedPointer退出作用域时会释放QEvent,导致postEvent处理过程中对QEvent的访问,或处理完事件后对QEvent的释放,都是错误的。

弱共享指针QWeakPointer

刚刚接触Qt的同学,在网上搜索文章时,对弱共享可能一知半解。QWeekPointer可以理解为与QPointer一样的追踪指针,QPointer目标是记录和追踪QObject对象,QWeekPointer则追踪的是QSharedPointer对象。

我在项目中通常很少使用弱共享指针,它的目的是作为QSharedPointer助手类,解除QSharedPointer的循环依赖,在面向对象设计中,出现循环依赖本身就不是一件理所当然的事。

关于智能指针的一些思考

智能指针是内存管理的工具,在语法层次上,为C++工程师降低了内存管理难度,能有效预防不经意笔误导致的内存泄漏,并减少了内存管理代码量。但是,智能指针本质上并不能解决项目中内存管理问题。

作为C++工程师,必须理解内存管理机制,明确的知道内存该何时创建、何时销毁。否则在选择哪种智能指针,用于管理目标内存时,不能做出正确的决定,还是会导致项目内存异常。除非未来Qt的某个版本,只有一个智能指针QPointer。

对于内存问题的解决,实际项目中我们更依靠QObject对象树和内存池。

04 对象树

Qt中用树形结构描述对象之间的父子关系,如下图,P为树的父节点,A2为一级子节点,B1、B2为二级子节点。
在这里插入图片描述
对象树内存的管理,当A2释放时,先释放B1、B2,再将自身从P的子节点列表中移除。

Qt对象树的特征,确保在父对象释放时,释放子对象内存,在实际项目中,我会经常使用。

QObject对象树的实现很容易理解,QObjectData中记录指向父对象的指针parent,和一个QList<QObject*>子对象列表children。

在UML中QObject描述为自己组合自己,意外不意外。
在这里插入图片描述

QObject延迟释放deleteLater

在QObject对象机制中,有一个非常好用的特性,deleteLater,其作用是延迟对象的析构。

什么意思呢,调用deleteLater后,QObject对象不会马上析构,而是在下一个消息循环析构。

使用的场景,比如容器中子控件的替换,可以避免画面闪烁,或者是其他一些需要延迟释放的地方。

05 内存池

大内存通常也叫内存池,其实内存池中管理的不仅仅是大内存,还有小内存。
在项目中,出于2种目的使用内存池,一是性能提升,二是避免内存碎片。

性能提升

对于频繁申请-释放小块内存的情况,使用内存池比new有显著的性能提升,但仅仅出于此目的,并没有充足的理由用到内存池。

避免内存碎片

对于内存池技术,更多的需要是避免内存碎片。

我在项目中曾经遇到,申请20M内存失败的情况,而此时系统内存明显大于20M,为什么呢,因为系统内存被碎片切割了,没有一块连续的20M内存。
在这里插入图片描述
在系统内存管理不够“聪明”时,C++程序员会有强烈的掌控欲望,希望一切都掌控在自己手中,包括内存的潜在风险。

通过内存池技术,在碎片切割导致内存不连续时,我们的程序有机会重新整理内存,满足申请大小。
在这里插入图片描述
关于内存池的技术,Qt并没有提供实现,但有很多开源的库参考,可以搜索“内存池”。
微信公众号
如果觉得文章有用请关注我的微信公众号

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt平台下C++内存管理 的相关文章

随机推荐

  • 孕妇有什么副业做?孕妇在家有哪些兼职可以做?

    孕妇有什么副业做 孕妇在家有哪些兼职可以做 孕妇在家选择兼职工作时 有一点一定要遵循 不能从事极端的体力工作 因为体力工作容易让孕妇出现并发症 所以孕妇一定要选择一些没有太大压力的兼职工作 有很多兼职工作时间很自由 所以特别适合怀孕的女性做
  • LAMP部署

    文章目录 LAMP简介 web服务器 web服务器的资源分为两种 静态资源和动态资源 工作流程 http响应报文 httpd与php结合的方式 httpd与php结合的方式有以下三种 lamp平台构建 环境说明
  • 不会下载软件?这5个网站别错过,纯净、安全、无捆绑

    虽然下载网站有很多 但是一不小心就会下载到各种捆绑安装包 这里就给大家分享5个比较靠谱的软件下载网站 纯净 安全 无捆绑 可以放心使用 1 Microsoft Store 一个微软旗下的电脑软件商城 它里面有很多类型的软件可以下载 首页也有
  • c/c++中,预编译指令用法汇总

    切换模式 写文章 登录 注册
  • java多线程实战( 多个线程 修改同一个变量)

    java多线程实战 多个线程 修改同一个变量 synchronized 同步 介绍 java多线程实战 需求 创建两个线程 分别输出 a b 要求输出总和为30个 线程介绍 一 定义线程 1 扩展java lang Thread类 此类中有
  • Makefile原理及使用

    makefile make 是一个命令工具 是一个解释 makefile 中指令的命令工具 make 工具在构造项目的时候需要加载一个叫做 makefile 的文件 makefile 关系到了整个工程的编译规则 文章目录 makefile
  • 前端Vue项目——课程详情页面实现

    一 详情页面路由跳转 应用 Vue Router 编程式导航通过 this router push 来实现路由跳转 1 绑定查看详情事件 修改 src components Course Course vue 文件 给课程 div 绑定查看
  • matlab基础语法1_变量类型_顺序循环

    1 变量 和c不同 matlab对于变量可以直接用 不用提前声明 和c一样 大小写敏感 和c一样 matlab的关键字不做变量名 使用iskeyword查看 和c一样 matlab的变量不能以数字开头 综上 和c编程类似 一定原因也是mat
  • OCV/ACOV的介绍

    OCV on chip variation 差异 芯片制造过程中 MOS见差异必然存在 Library中的cell delay是在某个固定的PVT下仿真得出的 而实际上芯片内部由于工艺偏差 电压降 温度变化 cell的delay并不是一个固
  • 进度条加载

    import datetime import time def show process counts 500 wait time 1 25 进度条总步数 steps counts 打印的 length 80 for step in ran
  • socket编程-TCP各函数及其用法

    socket编程 TCP socket主要类型 流套接字 SOCK STREAM 流套接字用于提供面向连接 可靠的数据传输服务 该服务将保证数据能够实现无差错 无重复送 并按顺序接收 流套接字之所以能够实现可靠的数据服务 原因在于其使用了传
  • Pseudo-Q: Generating Pseudo Language Queries for Visual Grounding, 2022 CVPR

    本文内容仅代表个人理解 如有错误 欢迎指正 1 Problem Background Information 1 1 Problem 目前 人们基本上都采用基于深度学习的方法来解决Visual grounding任务 不论是全监督学习还是弱
  • [转]VS2022\VS2019 VisualSVN License expires 解决办法

    步骤一 首先下载反编译工具 dnSpy gitHub下载地址 Releases dnSpy dnSpy GitHub 步骤二 查找VisualSVN安装目录 一般都在C目录下 步骤三 用dnSpy打开该dll 运行dnSpy exe 步骤四
  • CentOS8服务篇2:配置与应用Web服务

    Web服务器又称为WWW服务器 它是放置一般网站的服务器 一台Web服务器上可以建立多个网站 各网站的拥有者只需要把做好的网页和相关文件放置在Web服务器的网站中 其他用户就可以通过浏览器访问网站中的网页了 目前能够提供Web网络服务的程序
  • Flutter 网络请求和序列化

    一 网络请求 1 导入http dart import package http http dart as client 2 封装请求方法 封装的方法 getData cbk async var api getBaseUrl cats lv
  • 【转】Web网站通知系统设计

    写在前面 通知系统是网站信息传播机制的重要的一部分 足够写一大章来说明 本文只梳理设计原则 后续相关内容会持续更新 这里的通知包括但不限于公告 提醒或消息 不同使用场景下的功能定义不同 关于各客户端平台 ios android wp等 的通
  • ST-LINK USB communication error 非常有效的解决方法

    引言 我们在用ST Link下载程序的时候 经常会遇到ST LINK USB communication error的问题 其实解决方法很简单 更新一下固件库就行 如下图所示 首先检查确定是ST LINK USB communication
  • Android Preference隐藏,删除方式

    在Android系统开发中 经常需要去掉或者隐藏原生设置的一些条目 一 隐藏 Preference 方法 VisibleForTesting static final String ENABLE enable Preference enab
  • 用老版的python和pycharm好,还是新版的python和pycharm好?

    千万不要贪图新酷去下载和安装python和pycharm最新版 因为亲身经历 老版稳定 新版容易出问题 python用3 6 3 9的最好 pycharm用2021年的最好
  • Qt平台下C++内存管理

    分享我在编程中的设计观念 遇到的技术点 让我们在工作和生活中一起追求自由 这几年 自由的概念让我印象深刻 前不久看到一个词叫辞职自由 对 我刚刚辞职 站在新公司小山丘前 我想别人在实现财务自由的时候 我在追求加班自由 加班时努力搬砖 同时也