new运算符的几种优化

咱们一起学C++ 第一百八十八篇:之C++中全局new和delete运算符的重载探秘 大家好!C++作为一门强大的编程语言,在内存管理方面提供了丰富的机制。今天咱们来深入探讨C++中全局`new`和`delete`运算符的重载,希望通过这次学习,我们能对C++的内存管理有更深刻的理解,一起在编程的道路上不断进步! 阅读详情


近日在msn上,朋友提了一个令他比较难受的问题,他做的程序性能偏低,简单的看了一下,给出了几点常用的建议,现列如此:
通常,通过重新定义new运算符可以用来产生一些比较有趣的行为,但是注意如果重新定义了new运算符,那么也应该定义一个和它配套的delete运算符

1.固定大小的对象的频繁分配/释放
多数情况下的多数系统,应用程序是在一个接一个的分配内存块,那么当应用程序释放内存块的时候,在已分配的内存中将出现空洞。当应用程序再次出现新的分配需求时,new函数将搜索所有的空洞来查看是否此空洞大小足以容下所要求的容量(有的系统是必须大于要求的容量)。
通常情况下,系统的这种做法会很正常,但是当特定的需求出现时,就会有好的办法来优化它。那就是:当频繁的分配/释放固定大小的内存块时,每一次的再次分配,系统都要去搜索所有的空洞来匹配大小,即便你刚刚释放了一个大小相同的块,这种情况在驱动或者消息系统下将非常的严重,大部分对象将会频繁的分配,撤销。
那么我们可以在程序作以下优化,将每次释放的内存指针暂时保存在Pool中,当有分配需求时,如果Pool中有,那么返回给需求:
a.定义一个对象指针的数组,用来做缓冲池.例: Exp* Pool[CacheSize];
b.定义一个索引,指向当前的位置.例:int nPos = 0;
c.重载new/delete函数.   例:
void* Exp::operator new(size_t s)
{
 if( (s<sizeof(Exp)) && (nPos))
  return Pool[--nPos];
 else
  return ::operator new(s);
}

void Exp::operator::delete(void* p,size_t s)
{
  if(!p) return;
  if( (s<sizeof(Exp) && (nPos<CacheSize) )
   Pool[nPos++] = (Exp*)p;
  else
   ::operator delete(p);
}

2.虚拟存储系统中的系统颠簸
虚拟存储系统中,应用程序可以访问远大于物理空间的更多空间,OS将虚拟内存影射到主存上,并产生一个外页表。
如果应用程序要存取映射到主存内的虚拟内存,OS将置换出一个主存中的页。注:页的大小一般为4K,windows下用api可以得到SYSTEM_INFO   SI;
GetSystemInfo(&SI); DWORD aPageSize   =   SI.dwPageSize;
这时就会造成缺页中断,那么缺页中断的时间由3部分组成:缺页中断服务时间、将缺页读入的时间、进程重新执行的时间。
简单的来说就是慢100倍以上。大多数的应用程序中,系统将不常用的数据放到外页面表中,这样抖动不频繁时,应用程序会运行得很好。
通常的应用程序,在每次new内存块的时候,都会搜索整个内存空间来匹配一个区域,那么也就是说,对象将被分配于内存空间的各个地方。在最差状况里,当应用程序的堆大小等于主存大小时,如果new查找空闲区域,OS就要不停的将内外页交换,系统颠簸就会发生。
解决方法就是把相关的数据放在临近的内存中。例如:一个文档管理系统,将每个人的档案中的相关对象都分配到一个内存区块,也许会占用比以前多的内存,但是对于
虚拟存储系统来说,大小不重要,临近才重要。(这个例子举的并不怎么好,因为大部分文档管理系统,是不需要这种性能优化的)
那么重载一个new来做相关的分配是再适合不过了

3.利用重载的new运算符debug内存泄露
在new运算符中对引用计数++,在delete运算符中对引用计数--,在程序退出时,检查如果技术是>0的话,那么将有内存泄露发生。要是<0的话???
那应该是你多次删除了一个对象所致,一般半路就崩溃了,到不了程序退出这里。要检查一下你在局部删除一个对象后应该设它为NULL.
还有一个小技巧可以定位到底是哪里的指针泄露
#define new new(__FILE__,__LINE__) //unix下可能是_FILE_,_LINE_是编译器定义的全局宏,代表文件名和行数
那么重载new运算符后,可以自己管理一个数组来维护对应的文件和代码行数,当程序运行到最后,可以查看哪个index对应的
对象没有被释放,那么就可以print出对应的文件名和代码行数了。

写完了,欢迎批评~ 

咱们一起学C++ 第一百八十九篇:之C++中类专属的new和delete运算符重载 大家好!C++的内存管理一直是学习过程中的重点和难点,今天咱们一起深入探讨为类重载`new`和`delete`运算符的相关知识。我在学习这部分内容时收获很多,迫不及待地想和大家分享,希望我们能共同进步,更深入地理解C++编程! 阅读详情

相关推荐

C++中的new运算符:探索就地、普通和无抛异常new的用法

本文深入探讨了C++中标准提供的三种new运算符的变体:就地new、普通new和无抛异常的new,及其在特定类中的使用和重载。同时,分析了名称隐藏对全局new运算符的影响,以及如何在派生类中避免隐藏全局new运算符。...

weixin_26907223的博客 514

【C++】new和delete的实现原理

浅谈new和delete的实现原理

qq_45666995的博客 175

SAP OBYC自动过账全解析:从BSX到WRX的会计科目配置指南

本文深入解析SAP OBYC自动过账功能,从BSX到WRX的会计科目配置全流程,涵盖评估分组代码、事务码和评估类等核心概念。通过实战案例展示如何实现库存变动到财务过账的自动化流转,提升企业财务数据的准确性和效率。

weixin_29239279的博客 421

New(new 运算符)

New(new 运算符) new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。 new 关键字会进行如下的操作: 1. 创建一个空的简单JavaScript对象(即{}); 2. 链接该对象(设置该对象的constructor)到另一个对象; (为创建的对象添加属性和方法) 3. 将步骤1新创建的对象作为this的上下文 ;(构造函数的this指向新对象) 4. 如果该函数没有返回对象,则返回this。 // 若构造函数中返回this或返

SeriousLose 3144

从零到一:基于Matlab的二阶系统时域性能指标计算与可视化实战

本文提供了一份基于Matlab的二阶系统时域性能指标计算与可视化实战指南。通过详细的代码示例,手把手教你如何利用Matlab计算超调量、调节时间等关键指标,并绘制阶跃响应曲线进行可视化分析,帮助控制工程学习者和从业者快速掌握系统性能评估方法。

weixin_29096377的博客 271

别再死记公式了!用HFSS/CST手把手教你仿真一个2.4GHz WiFi的PIFA天线(附参数调试技巧)

本文详细介绍了使用HFSS和CST仿真软件设计2.4GHz WiFi PIFA天线的全流程,包括建模准备、分步操作指南和参数调试技巧。通过可视化结果和实战案例,帮助工程师快速掌握天线设计的关键参数优化方法,提升辐射性能和工作效率。

weixin_31682031的博客 336

C++中运算符new的深入讲解

本人深入讲解了C++中运算符new的使用方法

_Santiago的博客 9600

安装Codex时出现无法下载此应用和Microsoft Store初始化失败的解决方案

本文主要介绍了安装Codex时出现无法下载此应用和Microsoft Store初始化失败的解决方案,希望能对使用codex的同学们有所帮助。 文章目录 1. 问题描述 2. Windows 解决方案 3. Mac解决方案

weixin_43178406的博客 7万+

new与delete动态分配和释放内存

(1)new运算符使用的一般格式: new 类型 [初值]; 用new分配空间时不指定初值。如果由于内存不足等原因而无法正常分配空间,那么new会返回一个空指针NULL,用户可以更具该指针的值判断分配空间是否成功。 例如: new int;//开辟一个存放整形的存储空间,返回一个指向该存储空间的地址(指针)。 new int (100);//开辟一个存放整形的空间,并指定该整数的初值为100。 new *c=new char [10];//开辟一个存放字符数组的空间,返回首地址。 float *

qq_45288949的博客 4560

FISCO BCOS(八)——— 一键部署 WeBase

环境 版本 Java Oracle JDK 8 至 14 MySQL MySQL-5.6及以上 Python Python3.6及以上 PyMySQL 1、获取部署安装包: wget https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/WeBASE/releases/download/v1.5.4/webase-deploy.zip 2、解压安装包: unzip webase-deploy.zip 3、进入目录: c...

林中有神君 3608

Dify知识库文档批量下载神器:一键导出所有文件到本地

在使用Dify进行知识库管理的过程中,我们经常遇到一个实际问题:如何将已上传到知识库中的文档批量下载到本地?目前Dify的管理界面虽然功能强大,但暂时没有提供直接的UI界面来批量导出或下载知识库内的文档。这意味着如果我们需要将知识库中的文件备份到本地或进行离线处理,只能通过API接口来实现。本文将详细介绍如何利用Dify的REST API构建一个完整的知识库文档下载解决方案,这也是目前实现知识库文件批量下载到本地的唯一可行路径。🎉进入大模型应用与实战专栏 | 🚀查看更多专栏内容首先,我们需要在Dify的

羊城迷鹿的博客 3474

c++重载new操作符

new是C++里非常重要的一个关键词,用于申请内存、初始化对象。俗话说“有借有还再借不难”,通过new向操作系统“借”到的内存用完后必然要“还”回去,所以对应地还有一个delete操作符与new共同管理内存,delete的作用是析构对象、释放内存。 new有什么作用? 申请内存 初始化对象 说到内存管理,有些同学会想到C标准库函数malloc()和free()。C++是C语言的延续,那么C++一定可以丝滑地使用这两个标准库函数管理内存,那为什么还要提供关键词new和delete呢? 我们申请到内存后一般

米碎师兄 3929

Hadoop在大数据领域的电商数据分析案例

随着电商行业的迅猛发展,每天都会产生海量的数据,如用户浏览记录、购买行为、商品信息等。如何从这些数据中提取有价值的信息,为电商企业的决策提供支持,成为了电商企业面临的重要问题。Hadoop作为一个开源的分布式计算平台,具有高可靠性、高扩展性和高效性等特点,能够很好地处理大数据。本文的目的就是通过实际案例,详细介绍Hadoop在电商数据分析中的应用,范围涵盖了从数据采集、存储到分析的整个流程。本文首先介绍背景信息,让读者了解Hadoop在电商数据分析中的重要性和应用场景。

Java大师兄的博客 1179

详谈Javascript类与继承

转自:https://www.cnblogs.com/chengzp/p/extends.html 本文将从以下几方面介绍类与继承 类的声明与实例化 如何实现继承 继承的几种方式 类的声明与实例化 类的声明一般有两种方式 //类的声明 var Animal = function () { this.name = 'Animal'; }; //ES6中类的声明 class A...

Lyj的博客 219

SmartFusion从FPGA到ARM系列教程

前言 本系列教程,将会以Microsemi SmartFusion一代芯片A2F200M3F为例,简单介绍片上ARM Cortex-M3 硬核 MCU 基本外设的使用,及其与FPGA逻辑模块进行交互的示例。 在学习片上硬核ARM Cortex-M3 MCU的开发之前,要先熟悉Microsemi Libero SoC开发环境的使用,可以参考:Microsemi Libero SoC系列教程 关于Microsemi SmartFusion混合型FPGA的介绍,可以参考:Microsemi SmartFusio.

whik1194的博客 8293

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【c++深入系列】:new和delete运算符详解

学会并掌握new和delete运算符,看这一篇文章就够了!

努力努力再努力wz的博客 1560

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

[c++]placement new(定位new运算符)用法及用途

定位 new 运算符(Placement new)是 C++ 提供的一种特殊的 new 运算符,它允许在已经分配的内存地址上构造对象。这在需要精细控制对象内存布局的高级应用中非常有用,例如内存池、嵌入式系统和实时系统。

qq_63884623的博客 2353

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Js的new运算符

new运算符 在JavaScript中,new是一个语法糖,可以简化代码的编写,可以批量创建对象实例。 语法糖Syntactic sugar,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。 实例 假如我们不使用new,来初始化创建10个student对象实例 var stuGroup = []...

WindRunnerMax 1723

C++new运算符

new运算符虽然用的很久,但是我实际上对它的了解仅仅局限于表面知道和malloc一样可以在堆内存中申请内存,可能会调用对象的构造函数。但是具体的实现和什么时候调用构造函数完全不了解,因此今天在这里进行梳理。 1. new的常见用法 int *a =new int[5]; int *b =new A(); 在实际操作中,我们发现A的申请的空间的储存的值为随机值,new仅仅申请了一块随机空间,但是B的申请的空间的值已经初始化了,new调用了A的构造函数。 new A()的功能如下 在堆上申请空间 在分配的空

cat_want_fly的博客 741

C++ new 运算符学习笔记

C++动态内存管理摘要:new运算符用于堆内存分配,自动计算大小并调用构造函数,支持单个对象和数组分配(new[]/delete[])。提供多种初始化方式(默认/值/列表初始化),推荐使用智能指针(unique_ptr/shared_ptr)实现RAII管理。需避免内存泄漏、重复释放、悬空指针等问题。对比malloc,new具有类型安全、自动构造/析构等优势。现代C++实践建议优先使用make_unique/make_shared,对于特殊需求可定制operator new或使用定位new...

acsdnrb的博客 762

JS new运算符

js教程new是一个运算符,可以创建对象,初始化实例。其语法格式如下: newcontructor(arguments) constructor必须是一个构造函数表达式,参数arguments可有可无,参数之间用逗号分隔。如果没有逗号,可以省略小括号。 在最新的参考资料中,new已从运算符列表中被移出,作为命令使用,扮演多重角色。 示例1 下面代码使用new运算符实例化 Array,并演示 3种不同的使用方法。 var a = new Array; //创建数组,省略小括号 ...

Zzz9158的博客 234

new 运算符重载,placement new 用法

在使用placement new时我们可以预先分配一大块内存,然后在需要时使用 placement new 在其中创建对象,这样做可以避免频繁地分配和释放内存,优化性能。Placement new 允许在已分配的内存上构造对象,它不分配内存,只调用构造函数,通常用于内存池、自定义内存管理等场景。(4)placement new不分配内存,所以也不应该使用delete释放内存。(1)使用placement new时,必须确保内存块足够大且正确对齐。在使用placement new时必须要注意的事项。

black_sheeper的博客 331

【JavaScript】构造函数与 new 运算符

构造函数是用于创建和初始化对象的特殊函数,通过new关键字调用。JavaScript中有内置构造函数(如Object、Array)和自定义构造函数两种类型。使用new时,引擎会:1)创建空对象;2)设置原型;3)绑定this;4)执行构造函数代码;5)返回对象。构造函数应使用大驼峰命名(Person),普通函数用小驼峰(getUser)。不使用new会导致this指向错误,严格模式下会报错。构造函数默认返回新实例对象(this),即使没有显式return语句。

Superman_H的博客 550

定位new运算符

通常,new负责在堆区(heap)寻找一段满足要求的内存,除此之外,new还可称为定位运算符,用来指定要使用的内存的位置。要使用这种特性,需要在包含头文件。使用中要提供指定了地址的参数,其他用法和普通的new运算符一致。 char buffer[100]; int *p1,*p2; p1 = new int[20];//new的普通用法 p2 = new (buffer) int[20];//

u010675617的博客 166

C++ 内存分配(new,operator new)详解

本文主要讲述C++ new运算符和operator new, placement new之间的种种关联,new的底层实现,以及operator new的重载和一些在内存池,STL中的应用。 一 new运算符和operator new():      new:指我们在C++里通常用到的运算符,比如A* a = new A;  对于new来说,有new和::new之分,前者位于std      

少想多做 1563

C++的new和delete详解

new和delete的内部实现 C++中如果要在堆内存中创建和销毁对象需要借助关键字new和delete来完成。比如下面的代码 class CA { public: CA():m_a(0){} CA(int a):m_a(a){} virtual void foo(){ cout<<m_a<<endl;} ...

小白的逆袭 1万+
上一篇: 故障转储的linux与windows实现
下一篇: 程序员与微波炉食谱
code_farmer
博客等级 码龄22年 9粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值