问一下操作系统和C++内存的分配!

z752964360 2010-03-21 10:12:32
说windows操作系统的书一般会说给进程4gb的地址空间

我想问下是不是在这个进程中所有的堆,堆栈,静态存储区,都在这4gb就是用new,malloc分配的内存都在这里面?(应该是的)
如果都在这里面那进程结束时,内存就都收回来了?



在一个C++的问题,看C#的书说到.NET的内存回收,我想问一下C++只能手动回收内存?
那么,它这么保存这些内存碎片?判断给下一个new分配那里的内存?如果有的话那需要一个多大的数据结构啊!
.NET用堆得话就简单多了!
...全文
334 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
z752964360 2010-04-10
  • 打赏
  • 举报
回复
无奈,结贴了!
k0641302219 2010-03-27
  • 打赏
  • 举报
回复
跟着再顶
z752964360 2010-03-27
  • 打赏
  • 举报
回复
最后顶一次
z752964360 2010-03-26
  • 打赏
  • 举报
回复
如果程序结束,全局数据区和栈上的内存会被操作系统回收,堆上的不会被回收

真的?
z752964360 2010-03-26
  • 打赏
  • 举报
回复
更晕了
hellodudu 2010-03-25
  • 打赏
  • 举报
回复
c++没有gc是因为那样有可能会将整体的效率降低
如果你需要的话可以手写一个
但是gc的实现要考虑到很多情况
dos5gw 2010-03-25
  • 打赏
  • 举报
回复
C++只能手动回收
一个malloc必须对应一个free
一个new必须对应一个del
一个new[]必须对应一个del[]
TW_00001 2010-03-25
  • 打赏
  • 举报
回复
如果程序结束,全局数据区和栈上的内存会被操作系统回收,堆上的不会被回收
z752964360 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 redleaves 的回复:]

首先,你要了解所以平台硬件的运行方式.Win32运行的X86平台,在一般情况的保护模式下,一个任务可以有4G的地址空间.也就是我们所说的4G内存.这4G空间里包含了代码,数据等等所有进程要用的东西.这也是一般的32位程序地址有32位的原因.
而对于操作系统来说,内存限制一般是直接依赖于硬件的.所以Win32下,一个进程可以有4G的内存地址空间.但对于一个进程来说,并不是所有这4G地址都可用.一……
[/Quote]
X86 MMU的手册 C++的内存回收跟硬件关系很大?
hutrade 2010-03-25
  • 打赏
  • 举报
回复
为什么C++不搞个垃圾回收呢?不就是个链表操作嘛,指针链表C++是强项啊
Redo8228 2010-03-25
  • 打赏
  • 举报
回复
赞一个哈。

[Quote=引用 10 楼 redleaves 的回复:]
首先,你要了解所以平台硬件的运行方式.Win32运行的X86平台,在一般情况的保护模式下,一个任务可以有4G的地址空间.也就是我们所说的4G内存.这4G空间里包含了代码,数据等等所有进程要用的东西.这也是一般的32位程序地址有32位的原因.
而对于操作系统来说,内存限制一般是直接依赖于硬件的.所以Win32下,一个进程可以有4G的内存地址空间.但对于一个进程来说,并不是所有这4G地址都可用.一般……
[/Quote]
HUAXIANGDAGE 2010-03-25
  • 打赏
  • 举报
回复
DING DING
wangxipu 2010-03-25
  • 打赏
  • 举报
回复
虚拟内存,每个进程可以用2G,但是可以调整
ubiquitious 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hutrade 的回复:]
为什么C++不搞个垃圾回收呢?不就是个链表操作嘛,指针链表C++是强项啊
[/Quote]
何时回收?如何回收?
如果仅仅是个所谓的link pointer的话,那么C++的自动回收内存早就出来了。
如果能完美的回收内存那么C++ runtime 托管的虚拟机就出来了。
赵4老师 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hutrade 的回复:]
为什么C++不搞个垃圾回收呢?不就是个链表操作嘛,指针链表C++是强项啊
[/Quote]
为什么警察不管各家各户是不是锁好了门呢?不就是转一圈嘛。(^_^)
要是你们小区的警察或保安真的负责去锁好那些主人出门没锁或忘记锁的门,估计也是找骂。
redleaves 2010-03-25
  • 打赏
  • 举报
回复
首先,你要了解所以平台硬件的运行方式.Win32运行的X86平台,在一般情况的保护模式下,一个任务可以有4G的地址空间.也就是我们所说的4G内存.这4G空间里包含了代码,数据等等所有进程要用的东西.这也是一般的32位程序地址有32位的原因.
而对于操作系统来说,内存限制一般是直接依赖于硬件的.所以Win32下,一个进程可以有4G的内存地址空间.但对于一个进程来说,并不是所有这4G地址都可用.一般情况下,Windows会占用高2G地址,用来做系统管理,设备地址映射,共享内存等用途.所以,在这种情况下,应用程序只有不到2G的可分配内存.这些内存统一由OS进行分配和释放的管理.粒度比较大.所以只用占用比较少的内存就可以完全描述.在进程结束时,地址空间上所有已经使用的部分,都会由系统统一回收.
应用程序在分配/释放内存时,一般是不会直接使用操作系统的基本分配接口来完成的.C/C++里,通常是由运行时库,在初始化时向系统要一块足够大的内存,在上面建立堆.然后使用堆来进行分配. 其实操作系统在创建进程时,会自动为进程初始化一个堆.但通过操作系统调用,性能上会有比较大的影响.所以一般运行时库会对系统的堆做再包装.
以上是X86上内存管理的基本层次. 在不同的层次上,都有独立的内存管理机制来确保它在设计范围内的功能和性能.而在不同层次上碎片的处理也不同.在OS底层,最小的内存粒度一般是页.所有的分配都是以页为单位.这个层面不会产生一般意义的碎片.只是会将连续的地址分割成不连续的地址段.系统只用维护少量的地址表就可以达成功能(因为粒度大). 在应用程序层面, 内存由堆管理.堆也有它的最小内存分配粒度. 通常会是2^N大小. 由于堆本身就是大块内存,所以一般不用再分配其它的内存来管理堆自身. 堆中每一个可分配块都是一个可用的数据节点,用来保存它自己的信息.所以,在建立堆时,就已经创建好了一个足够大的数据表,完全可以应付内存分配中所有要记录信息.


综上:
>>我想问下是不是在这个进程中所有的堆,堆栈,静态存储区,都在这4gb就是用new,malloc分配的内存都在这里面?
是的.
>>如果都在这里面那进程结束时,内存就都收回来了?
对,在进程结束时,进程的地址空间会被释放.它的页表,及页表项也就相应的要释放.这时,所占用的物理内存就被回收了.
>>在一个C++的问题,看C#的书说到.NET的内存回收,我想问一下C++只能手动回收内存?
C/C++中的动态内存管理是由用户做的.但它只是说你要做分配,和释放的动作.并不用你去管具体的细节.
>>那么,它这么保存这些内存碎片?判断给下一个new分配那里的内存?如果有的话那需要一个多大的数据结构啊!
用户不用直接管理碎片.堆会自动管理,它自动记录可分配内存表,在分配时从表中取适合的一项出来给用户.由于碎片本身就是内存,它就可以在自身的内存里记录自己的信息.不用浪费额外的内存.

另:我上面的的描述只是概要性的.像物理地址,虚拟地址之类的细节没有提及.具体的细节,请参考X86 MMU的手册,OS的手册以及编译器手册.
cattycat 2010-03-25
  • 打赏
  • 举报
回复
4G内存并不是你的程序完全可以用的,事实上你一次malloc4G也不一定给你分配这么多,只有你真正写数据的时候才会被你分配。而且真正的物理内存的部分是内核占用的,一般应用程序不能占用这么多,事实上就被放到了磁盘上的交换区了。
z752964360 2010-03-24
  • 打赏
  • 举报
回复
没人回答啊
z752964360 2010-03-23
  • 打赏
  • 举报
回复
顶下,看看有好的答案没
tj_swjtu 2010-03-22
  • 打赏
  • 举报
回复
学习一下
加载更多回复(6)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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