最近 看到一些与释放内存相关的课题。非常不理解其中的原因。目前知道(仅仅是知道),
c++  申请了内存,堆上的空间不用时需要释放。
c#   堆上的对象实例占据的内存,在对象无效时,垃圾收集自动释放内存。  从所谓的原理上,我很理解。以前的一些变量,对象,占据了内存的空间。不用了,释放掉,清空“垃圾”的感觉。以后会仍然有较多的空间去用,不至于没有空间(内存溢出)的错误出现。   但是,不明白的是,所谓的申请内存与释放内存在 实际的内存中发生了什么呢??   比如,0x10000-0x1FFFF的内存地址,被申请内存函数申请了。那么,该怎么理解这个申请了呢??
   在释放之前,其他的函数不能再申请这段空间??  这段空间的地址范围在内存的其他地方存储起来了?? 编译器会在生成的代码中,有管理这个功能的相关二进制代码??(当然,源程序中怕是不会有这些代码的吧,否则也不会这么疑惑了)   那释放这段内存呢?? 意味着可以重新被申请这段地址空间???否则就不允许再申请这段空间???这段内存中的数据仍保留之前的状态?比如之前是0110010。
   如果是c++,是不是因为有指针,也许会不小心因为某些操作又重新指向了这段地址从而出现错误??但java中,没有指针。是不是意味着只是内存空间的浪费?
   还有,所谓的释放内存是什么概念呢??  在程序的某段内存空间中标记此内存地址范围可用??  还是把此内存地址范围都清零??比如之前的任何数据,都恢复为0000000。
    
   

解决方案 »

  1.   

    那就是所谓的薄记工作了,只不过是有那么一段程序在记下了当前哪里内存是申请过了的,还记下了申请的内存的长度,
    清理的时候就是把那记录清掉罢了,好像是那么一回事,数据仍然会保存之前的状态的。
    当中过程你可以在调试的时候跟踪new,一步一步跟踪下去,,嘿嘿,,一大堆的代码看得你头疼呀..
    java中肯定也用到指针,不过不是我们可以用到的罢了。
      

  2.   

    我想应该是编译的概念吧,不属于CPU具体操作动作的那种。当作一种逻辑关系来理解。
      

  3.   

    http://www.cnblogs.com/qiubole/archive/2008/03/07/1094677.html
      

  4.   

    楼上的贴的很好,可惜不是楼主疑惑的问题楼主这个问题,据我的理解,是和操作系统密切相关的操作系统有个内存管理机制,程序申请N字节的内存时,是向操作系统申请的。操作系统检查自己维护的内存使用记录,查找到第一个长度大于等于N的空闲块,把这块的前N个字节标记为供给某进程使用,并更新内存使用记录,返回此块的首地址给程序。也就是说,真实内存的管理是与OS相关的,程序管理自己申请到的那些内存。以下两个问题,若不明白操作系统在此担当的角色,是很难理解的:1、有时候,为何明明空闲内存还有很多M,我申请一块1M的内存居然报错说内存不足?解释:虽然空闲内存总和还有很多,但是都是碎片,没有一个空闲块长度大于等于1M2、c/c++程序申请了内存从不释放,有内存泄露,那么关闭程序后(彻底退出所有线程),那些内存会被释放么?解释:会。因为OS知道这个进程申请了那些内存,进程结束时,OS会清理所有与之相关的资源,包括内存。
    希望对楼主能有所帮助。详情请参阅操作系统原理。清华出版社有一版不错的。
      

  5.   

    内存在操作系统是"一块一块"进行管理, 通常我们称之为"页面".而内存的每个页面, 都有自己的"属性". 这个属性记录了内存类型, 状态, 保护模式, 用途, 进程信息等内容.比如, 内存页面状态是"PAGE_READONLY", 那么这个时候你是不能写东西的, 尝试写入将会引发操作系统异常.
    当你使用malloc, Java/C#的new操作符"申请"内存时, 操作系统会尝试在堆上找出连续的内存页面, 直到总的内存大小符合你的需要, 然后改变这些内存页面信息, 将属性设置为你的程序可读写. 这样, 你就能"使用"这段内存.释放内存, 就是通知操作系统重新设置内存页面的属性, 操作系统可以考虑讲这块内存分配给其他程序. 至于内存上保存的数据会不会马上"清楚", 这取决于操作系统设计.