什么是申请内存 释放内存 这时cpu都作了什么??

iloveppmm 2009-04-01 05:36:00
最近 看到一些与释放内存相关的课题。

非常不理解其中的原因。

目前知道(仅仅是知道),
c++ 申请了内存,堆上的空间不用时需要释放。
c# 堆上的对象实例占据的内存,在对象无效时,垃圾收集自动释放内存。

从所谓的原理上,我很理解。以前的一些变量,对象,占据了内存的空间。不用了,释放掉,清空“垃圾”的感觉。以后会仍然有较多的空间去用,不至于没有空间(内存溢出)的错误出现。

但是,不明白的是,所谓的申请内存与释放内存在 实际的内存中发生了什么呢??

比如,0x10000-0x1FFFF的内存地址,被申请内存函数申请了。那么,该怎么理解这个申请了呢??
在释放之前,其他的函数不能再申请这段空间?? 这段空间的地址范围在内存的其他地方存储起来了?? 编译器会在生成的代码中,有管理这个功能的相关二进制代码??(当然,源程序中怕是不会有这些代码的吧,否则也不会这么疑惑了)

那释放这段内存呢?? 意味着可以重新被申请这段地址空间???否则就不允许再申请这段空间???这段内存中的数据仍保留之前的状态?比如之前是0110010。
如果是c++,是不是因为有指针,也许会不小心因为某些操作又重新指向了这段地址从而出现错误??但java中,没有指针。是不是意味着只是内存空间的浪费?
还有,所谓的释放内存是什么概念呢?? 在程序的某段内存空间中标记此内存地址范围可用?? 还是把此内存地址范围都清零??比如之前的任何数据,都恢复为0000000。


...全文
447 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
wartim 2009-04-02
  • 打赏
  • 举报
回复
你去找一本操作系统的教科书来看就知道了
shrinerain 2009-04-02
  • 打赏
  • 举报
回复
内存在操作系统是"一块一块"进行管理, 通常我们称之为"页面".

而内存的每个页面, 都有自己的"属性". 这个属性记录了内存类型, 状态, 保护模式, 用途, 进程信息等内容.

比如, 内存页面状态是"PAGE_READONLY", 那么这个时候你是不能写东西的, 尝试写入将会引发操作系统异常.


当你使用malloc, Java/C#的new操作符"申请"内存时, 操作系统会尝试在堆上找出连续的内存页面, 直到总的内存大小符合你的需要, 然后改变这些内存页面信息, 将属性设置为你的程序可读写. 这样, 你就能"使用"这段内存.

释放内存, 就是通知操作系统重新设置内存页面的属性, 操作系统可以考虑讲这块内存分配给其他程序. 至于内存上保存的数据会不会马上"清楚", 这取决于操作系统设计.




天乐 2009-04-02
  • 打赏
  • 举报
回复
楼上的贴的很好,可惜不是楼主疑惑的问题

楼主这个问题,据我的理解,是和操作系统密切相关的

操作系统有个内存管理机制,程序申请N字节的内存时,是向操作系统申请的。

操作系统检查自己维护的内存使用记录,查找到第一个长度大于等于N的空闲块,把这块的前N个字节标记为供给某进程使用,

并更新内存使用记录,返回此块的首地址给程序。

也就是说,真实内存的管理是与OS相关的,程序管理自己申请到的那些内存。

以下两个问题,若不明白操作系统在此担当的角色,是很难理解的:

1、有时候,为何明明空闲内存还有很多M,我申请一块1M的内存居然报错说内存不足?

解释:虽然空闲内存总和还有很多,但是都是碎片,没有一个空闲块长度大于等于1M

2、c/c++程序申请了内存从不释放,有内存泄露,那么关闭程序后(彻底退出所有线程),那些内存会被释放么?

解释:会。因为OS知道这个进程申请了那些内存,进程结束时,OS会清理所有与之相关的资源,包括内存。


希望对楼主能有所帮助。

详情请参阅操作系统原理。清华出版社有一版不错的。
wuyq11 2009-04-01
  • 打赏
  • 举报
回复
http://www.cnblogs.com/qiubole/archive/2008/03/07/1094677.html
风骑士之怒 2009-04-01
  • 打赏
  • 举报
回复
学习 ... 意义上的占用吗? 本人愚见
jsstb 2009-04-01
  • 打赏
  • 举报
回复
我想应该是编译的概念吧,不属于CPU具体操作动作的那种。当作一种逻辑关系来理解。
gzvigo 2009-04-01
  • 打赏
  • 举报
回复
那就是所谓的薄记工作了,只不过是有那么一段程序在记下了当前哪里内存是申请过了的,还记下了申请的内存的长度,
清理的时候就是把那记录清掉罢了,好像是那么一回事,数据仍然会保存之前的状态的。
当中过程你可以在调试的时候跟踪new,一步一步跟踪下去,,嘿嘿,,一大堆的代码看得你头疼呀..
java中肯定也用到指针,不过不是我们可以用到的罢了。

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧