new 出来的存储空间(如果不使用delete),系统会自动回收?

C++对象池自动回收技术实现(重载new和delete运算符) 对象池模型适用的场景 、效果 、实现重载new和delete运算符实现对象池自动回收技术 阅读详情

http://blog.sina.com.cn/s/blog_4aecb7bd010006gb.html

 

new 出来的存储空间(如果不使用delete),系统会自动回收?!

 (2006-11-12 11:41:12)

转载

 

分类: 编程语言C

标  题: Re: new出来的空间系统会不会自动回收?
发信站: BBS 哈工大紫丁香站 (Sat May 15 09:25:05 2004)

  
 看见N本书这样说过,对于现代操作系统而言,是可以不delete的,其实new操作到最后会被编译器链接到malloc上,是调用的malloc,而malloc是一个系统调用,用来分配内存。因此,内存的分配最终是由操作系统而不是由编译器完成的,编译器只是起个调用系统调用以分配内存的的动作,而真正怎么分配是由操作系统决定的.

一般操作系统都有一块很大的自由内存区,这块自由内存区也称为堆,当你用new分配这块内存的时候,也被称为在堆上分配,当你用new产生一个操作系统调用,要求分配内存的时候,操作系统就检查这块堆,检索出一块大小合适的且被标记为“未分配”的内存,并返回它的指针,然后再把这块内存标记为“可分配”,当你调用delete的时候,操作系统再清除这块内存的”可分配“标记,以便可以再次分配这块内存。这就是一个最最简单的内存分配动作,打个比喻,操作系统就像银行,new就像你向银行借钱打个借条,delete就像你还钱的时候,银行取消掉借条.以前还有问,为什么在delete后,还可以操作这块内存,而不出现段错误?从上面的描述中可以看出,delete后的内存还是在内存空间中,只是重新被操作系统标记为“可分配”了,因此你当然还可以对其进行操作,只不过,你并不知道它在什么时会被分配出去,如果它被分配出去了,你对此块内存的操作就非常危险了。

   
 当然,一个健壮的操作系统完全可以在你访问不属于你的内存时(或者访问被标记为"可分配"的内存时),产生一个错误中断或错误陷阱,这主要看操作系统的怎么管理的了。一个非常健壮的操作系统也许会检测所有对堆内存的访问,如果发现你访问了一块不是你的内存,就会出错。而这样的检测是比较费时间的,因此,有些操作系统可以选择只对”已分配“的内存进行这样的检测,于是,在此块内存被delete重新标记为”可分配“到被重新分配前,你可以继续对此内存进行操作,而一旦此内存被重新分配出去,内存标记表为“已分配”,这时,你再继续使用这块内存时,操作系统就会报错了。这样,有时后你访问已delete的内存时,不会出错,而有时又会出错,这就是由于在先前这块内存还未被分出,操作系统不检测你对此内存的访部是否合法,因此没出错,但下次你再访问时,这块内存已被分给其它进程使用了,因此,操作系统会对这个内存进行检测,于是就出错了.

 

 

    对于一些采用页式管理的操作系统,最底层的内存分配一次分配一页(4KB),然后在其上实现一层高级内存管理,以便用你可以分配指定大小的内存而不是一整页了,当一页上的所有空间全部被delete,即全部标记为“可分配”时,操作系统就会将这页的存在标记置为“不存在”,然后将其从内存中去除,并在页表中去除,这样,当重新访问时,CPU会产生缺页中断,操作系统会对这样的中断进行处理,处理或许是会重新载入此页,或许是产出一个错误,因为操作系统发现你已经delete了,无权再访问此页了,要访问,你需要重新new.

 

    因此,这就会出现一个非常有趣的现象:你delete了一块内存,然后不停的访问,前99次都可以,而第100次就不行了,这或许就是因为前99次时,因为此页上还有其它进程没有delete的空间,而第100次时,其它进程洽好全部delete了,于是操作系统把此页作废了,你再访问时,操作系统就会发现你是非法访问,于就就出错了。因此,99次运行正确的程序,不见得第100次运行就会正确!这样做的好处就是,操作系统只在产生缺页中断的时候,才检测内存访问是否合法,由于内存访问是很频烦的操作,降低检测次数,当然就可以系统效率升高。操作系统在分配内存时,会建立一个数据结构,对一块已分配的内存保留它的很多信息,比如这块内存的首地址,大小。因此,才会有这样一种显象,当malloc或new一块内存时,你需要指定要分配的内存大小,而当你free或delete时,却不需要指定大小,而只需给出内存的首地址指针就可以了,这主要是因为,操作系统只需要把这块内存重新标记为”可分配“,而其内存大小,在操作系统分配内存时,操作系统就自动把它记录下来了。

   
 现代操作系统,在分配内存时,还会记录内存被分配给哪个进程了,这样,当进程在退出的时候,就完全可以强制性回收所有的分配给这个进程的空间。当然,如果一个操作系统在分配内存时,并没有记录这块内存并分配给谁了,那么它就不能强制回收一块内存,这时就需要你必须用delete。这样的情况主要出现在古董级的操作系统上,因为当时的内存非常有限,不允许操作系统如此大方的用它来存储它需要存储的信息,不过,对于现在来说,保存一下内存被分配给那个进程了实在是小case,因此,现在你可以不太注意是否使用了delete了,不过用delete会及时的释放内存空间,但不用delete,却只会在进程完蛋时才释放,这其间的区别,自然就不用多说了。

   
 不过我想提醒一下,操作系统强制回收不等于我们常常说的“垃圾回收机制!”,看看java,它的垃圾回收机制,它是先不断的分配内存,只要能分配就分配,如果不能分配了,它再查找一下哪些内存已经不被程序使用了,它就回收它,但操作系统强制回收机制却没有这样的能力,它不知道哪些内存已经不被程序使用了,对于它而言,只要是没有delete的内存,它就认为程序还在使用它。说简单一点,对于java或C两个程序,如果都只用new而不用delete,那么java可以在程序运行的过程中就回收内存,而c的程序却不行,只能在程序运行结束后,由操作系统一次性强制回收,java是边用边收,程序可以永远运行,而c是只用不收,当最后没有再能用的时候,程序不得不被杀除,这时操作系统再回收,于是,如果你在java中用for(;;)new...,java程序可以一直运行下去,而c却总用内存用尽的时候。

   
 那么是否是所有的new,都可以不delete呢?这也不见得,有的操作系统会在内存分配的时候,除了保留内存分配的指针及大小外,还要保留一个类型参数,用来标记这个内存是进程单独使用,还是多进程共用。如果是单独使用,当然可以在进程结束时,由操作系统自动回收;如果是多进程共用,这当然就不行了,因为,此进程虽然结束了,但还有进程在使用,因此不能回收。在多进程共用内存的分配上,这很大可能是由引用计数实现的,每块内存都有一个引用计数值,最初的引用计数值是0,new一次就+1,delete一次就-1,只有当其值为0时,才会被操作系统真正回收,这时,如果你new了,但没有delete,则引用计数就不可能成为0,这块内存就会一直被保留,而无法被操作系统回收,这种情况下,你就必须在new后delete了。

   
 内存的分配是由操作系统完成的,而不是由编译器完成的,malloc,new等等,只是一个系统调用,它调用操作系统的内存分配函数来完成内存分配的功能,而具体怎么分配是操作系统决定的,编译器无法决定,也无法知道,因此,这是平台相关,而编译器无关的。

   
 各个操作系统对于内存分配的策略各有不同,反正是CPU就提供了那些功能,在这些功能上,怎么实现以满足需求是八仙过海,各显神通,这没有参考资料,也没有标准答案,linux为了满足它的需求,采用了一种实现方式,而windows为了满足它的需要,采用了另一种实现方式。像pyos,我的想法是提供一个功能更强一点的内存管理,比如,一个进程可以申请分配一个共享内存区,而只有申请分配的内存具有写权限,而其它进程只具有读权限,这又是另外一种内存分配策略。我想我们可以提出一个需求,然后讨论可以用什么方法实现这样的需求,可以讨论linux或windows为什么要这样实现,而不是讨论linux或windows怎样实现,不是讨论应当怎样实现,或者去讨论书上说怎样实现。

原文:http://purec.binghua.com/Article/ShowArticle.asp?ArticleID=130

 

文章引用自:http://blog.youkuaiyun.com/xiaohan13916830/archive/2004/06/30/30102.aspx

 

ABAP on HANA/CDS view/AMDP 大乱炖 文章目录1. HANA的三大杀器1.1 内存式数据库1.2 多核架构1.3 列式存储1.3.1 数据压缩1.3.2 并行处理1.3.3 聚集和索引1.3.4 代码下移2. CDS 概念2.1 ABAP 开发环境2.2 OPEN SQL语句2.3 CDS 到底是啥2.4 CDS 类型2.5 创建CDS view3. CDS 实战3.1 Annotation注解3.2 Case 语句3.3 数学计算3.4 字符串表达3.5 货币转换3.6 聚集语句3.7 Join3.8 Union3.9 参数3.10 作为子C 阅读详情

相关推荐

实战:如何用MIPI CSI-2高效传输RAW10图像数据(附带宽优化技巧)

本文深入探讨了MIPI CSI-2协议在RAW10图像数据传输中的高效应用,详细解析了4像素5字节打包机制及其带宽优化技巧。通过动态Lane分配、位深度自适应压缩和虚拟通道交错传输等实战方法,显著提升传输效率,适用于IoT摄像头开发等低功耗场景。

css33的专栏 731

C#学习笔记(1)

C#学习笔记(1)

Luuda0808的博客 784

Stata:手动安装ivreghdfe包的完整指南与常见问题解决

本文提供了Stata中手动安装ivreghdfe包的完整指南,包括准备工作、详细安装步骤及常见问题解决方案。ivreghdfe作为处理高维固定效应模型的强大工具,依赖ftools、reghdfe和ivreg2三个核心组件,手动安装可避免版本冲突问题。文章还分享了进阶使用技巧,如并行计算加速和保存固定效应估计值,助力用户高效完成工具变量回归分析。

weixin_29251131的博客 928

使用new分配存储空间后必须用delete释放吗,为什么? 实践测试了一下用new后无论用不用delete进行释放程序都可运行,...

是的,在使用 new 分配存储空间后,必须使用 delete 释放。这是因为 new 操作会在堆上分配内存,而不是在栈上。如果不使用 delete 释放内存,可能会导致内存泄漏。即程序运行结束后,内存仍然被程序占用,导致系统资源浪费。 然而,在你实际测试中没有发现错误是因为编译器可能会在程序结束时自动释放未释放的内存,但这不是可靠的做法,因为它可能在其他系统中不会有这样的情况。 ...

weixin_42600128的博客 2380

图学习——04.HAN(异构图注意力网络)

什么是异构图,什么是元路径,什么是HAN,怎么计算attention,节点级别的attention和语义级别的attention

m0_51474171的博客 2998

基于STM32设计的环境监测系统(华为云IOT)_300

随着空气污染问题日益严峻,环境空气质量的监测变得愈加重要。为了解决这一问题,本项目设计并实现了一款基于STM32的空气质量监测设备,能够实时监测空气中的温湿度、二氧化碳浓度和甲醛浓度,并通过OLED显示屏展示数据。此外,设备支持通过WIFI模块将数据上传至云端,用户可以通过手机APP或Windows上位机查看实时数据。设备采用MQTT协议与华为云IOT物联网服务器进行数据通信,确保数据的实时性和可靠性。本项目还结合了低功耗设计和高灵敏度传感器,使得设备能够高效稳定地运行,并实现远程监控功能。

695

new之后没有delete会造成内存泄漏

new之后没有delete会造成内存泄漏。

d1428428的博客 924

openclaw : 无法将“openclaw”项识别为 cmdlet、函数、脚本文件或可运行程序的名称 解决方案

本文主要介绍了openclaw : 无法将“openclaw”项识别为 cmdlet、函数、脚本文件或可运行程序的名称解决方案,希望能对使用openclaw的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 12万+

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万+

Autosar_MCAL_Port

PORT Driver就是对微控制器(MCU)的整个PORT模块进行初始化配置。很多端口和管脚被分配有多种不同的功能,即可以进行引脚功能复用,比如通用I/O、adc、pwm、spi等功能。因此,对PORT必须有一个整体的配置和初始化,对各管脚的具体配置和使用取决于微控制器和ECU的引脚功能分配。PORT初始化数据应当尽可能高效地写到每个端口。DIO驱动中所用到的端口的配置和初始化都是在PORT驱动模块中完成的。因此,在使用DIO功能之前,应先进行PORT的初始化。1、PortContainer说明。

不断debug,优化中…… 238

fanuc机器人I/O分配

FANUC机器人在和其他外部设备进行通讯时,需要对信号进行配置。 在机器人处于UOP自动分配状态时,系统会自动检索已配对设备,并分配相应的机架号。 当我们需要手动对信号进行分配时,可参考以下机架号进行配置。 不同的通讯协议对应的机架号不同,外部通讯协议常用的机架号参考下表: 序号 机架号 通讯类型 1 0 Process I/O 2 1-15

haier123888的博客 1万+

c++中new和delete的使用方法

c++中new和delete的使用方法

魏波 4449

【MATLAB】嵌入式PID控制参数整定与优化

本文提出了一种基于MATLAB仿真的嵌入式PID参数优化方法,解决了传统人工试凑法效率低、适应性差的问题。通过建立一阶滞后被控对象模型,对比分析了不同PID参数组合的性能表现,筛选出最优参数。仿真结果表明,优化后的PID参数能有效降低超调量(从传统方法的显著超调降至接近0%),缩短调节时间,提高稳态精度。最终将优化算法部署到STM32平台,实现了"仿真整定-参数优化-嵌入式落地"的完整开发流程。该方法显著提升了嵌入式系统的响应速度和控制精度,为工业控制应用提供了标准化解决方案。

unber的博客 45

c++ new操作符(new operator)、operator new、placement new 、operator new[] 及相对应的delete 操作符、operator delete

一.new new operator就是new操作符,不能被重载,假如A是一个类,那么A * a=new A;实际上执行如下3个过程。 (1)调用operator new分配内存,operator new (sizeof(A)) (2)调用构造函数生成类对象,A::A() (3)返回相应指针 事实上,分配内存这一操作就是由operator new(size_t)来完成的,如果类A重载了operator new,那么将调用A::operator new(size_t ),否则调用全局:...

baidu_16370559的博客 2639

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

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

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

使用new和delete实现动态内存的分配和回收

为什么要用new和delete分配动态内存的分配和回收? 在C++/C语言的标准库函数我们用malloc与free实现动态内存单元的分配与回收,注意 malloc和free是库函数而new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。但使用new/delete显然要比使用malloc/free运行程序效率更高。 对于非内部数据类型的对象而言,光用maloc/free无法满足...

weixin_46255747的博客 632

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java用new忘记delete会怎样_c++中new和delete的使用方法

http://www.jb51.net/article/49537.htm对于计算机程序设计而言,变量和对象在内存中的分配都是编译器在编译程序时安排好的,这带来了极大的不便,如数组必须大开小用,指针必须指向一个已经存在的变量或对象。对于不能确定需要占用多少内存的情况,动态内存分配解决了这个问题。new和delete运算符是用于动态分配和撤销内存的运算符。一、new用法1.开辟单变量地址空间使用ne...

weixin_42546508的博客 1650

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

new和delete

new和delete是运算符,不是函数。 new new运算符的例子: new int;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针) new int(100);//开辟存放一个整数的空间,并指定该整数的初值位100,返回一个指向该存储空间的地址 new char[10];//开辟一个存放字符数组(包括10个元素)的空间,返回字符数组首元素的地址。 new int[...

weixin_45634839的博客 392

C++中关于new和delete的使用

最近一直在啃 C++ Primer 中文版第4版,发现 C++中new和delete应用遍布全书,现对其使用作简单总结。在C++中,可以使用new和delete动态创建和释放数组或者单个对象,现在对它们的使用一一道来。 1.创建动态数组         数组类型的变量有三个重要的限制:数组长度固定不变,在编译时必须知道它的长度,数组只在定义它的块语句中存在。对 C++中关于new和d

林一鸣的专栏 2万+

c++的new和delete的方法使用以及不用new定义变量

new和delete运算符用于动态分配和撤销内存的运算符 new用法:           1.     开辟单变量地址空间                1)new int;  //开辟一个存放数组的存储空间,返回一个指向该存储空间的地址.int *a = new int 即为将一个int类型的地址赋值给整型指针a.                 2)int *a =

uestcyao的专栏 9533

浅谈C++中new以及delete使用

对于计算机程序设计而言,变量和对象在内存中的分配都是编译器在编译程序时安排好的,这带来了极大的不便,如数组必须大开小用,指针必须指向一个已经存在的变量或对象。对于不能确定需要占用多少内存的情况,动态内存分配解决了这个问题。 对于个人感触最深的就是数组了,数组有三个重要的限制:(1)数组长度固定不变;(2)在编译时必须知道数组的长度;(3)数组只在定义它的块语句内存在。实际的程序往往不能忍受这

lkn910907的专栏 862

c++ 中new 和 delete的使用方法

c++中new和delete的使用方法http://www.jb51.net/article/49537.htm对于计算机程序设计而言,变量和对象在内存中的分配都是编译器在编译程序时安排好的,这带来了极大的不便,如数组必须大开小用,指针必须指向一个已经存在的变量或对象。对于不能确定需要占用多少内存的情况,动态...

haiki66的博客 924

C++中new和delete的用法

首先,new和delete运算符是用于动态分配和撤销内存的运算符。 一、new用法   1.开辟单变量地址空间   使用new运算符时必须已知数据类型,new运算符会向系统堆区申请足够的存储空间,如果申请成功,就返回该内存块的首地址,如果申请不成功,则返回零值。   new运算符返回的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过该指针来间接操作的,而动态创建的对象本

fenxinzi557的博客 895

new与delete用法详解

一.new的用法: 1. new() 分配这种类型的一个大小的内存空间,并以括号中的值来初始化这个变量; 2. new[] 分配这种类型的n个大小的内存空间,并用默认构造函数来初始化这些变量; 例子: #include #include using namespace std; int main(){ char * p=new char("Hello"); //error分配一个

Sucre 1767
上一篇: C++中cout与指针问题
下一篇: 递归和动态规划
DeepIT
博客等级 码龄16年 27粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值