嗯,我很抱歉,如果这感觉就像重复旧问题一样,我已经通过Tanenbaum对Stack Overflow,现代操作系统手册进行了几个问题,并且仍然要清除我对此的怀疑。
首先,我将非常感谢我应该更详细地阅读的任何书籍/资源,以便更好地理解这种结构。我不明白这些是OS书籍,编程语言或架构书籍中通常解释的概念。
在我提出问题之前,我会根据有关堆栈/堆的读数列出我的发现
堆
堆栈
现在,关于我的一些问题。
我知道这很多,而且我似乎总是非常困惑,如果你能指出我正确的方向让这些事情得到澄清,我将不胜感激!
答案 0 :(得分:7)
全局变量分配在编译时布局的内存的静态部分中。在输入main
之前启动期间初始化值。当然,初始化可以在堆上进行分配(即静态分配的std::string
将使结构本身位于静态布局的内存中,但是它包含的字符串数据在启动期间在堆上分配)。在正常程序关闭期间删除这些内容。在此之前你不能释放它们,如果你愿意,你可能想要将值包装在指针中,并在程序启动时初始化指针。
堆由分配器库管理。 C运行库附带了一个,但也可以使用tcmalloc或jemalloc之类的自定义代码来代替标准分配器。这些分配器使用系统调用从操作系统获取大型页内存,然后在调用malloc时为您提供这些页面的一部分。堆的组织有点复杂,并且在分配器之间有所不同,您可以查看它们在网站上的工作方式。
是肥胖型。虽然您可以使用像alloca
这样的库函数在堆栈上创建一大块空间,并将其用于您想要的任何内容。
每个进程都有一个单独的内存空间,也就是说,它认为它是独一无二的,并且不存在其他进程。一般来说,如果你要求它,操作系统会给你更多的内存,但它也可以强制限制(比如linux上的ulimit
),这时它可以拒绝给你更多的内存。碎片不是操作系统的问题,因为它在页面中提供内存。但是,过程中的碎片可能会导致分配器要求更多页面,即使空白也是如此。
是
是的,但是通常有特定于操作系统的方法来创建多个进程可以访问的共享内存区域。
堆栈溢出本身不会崩溃,它会导致内存值写入可能包含其他值的位置,从而破坏它。对损坏的内存进行操作会导致崩溃。当您的进程访问未映射的内存时(请参阅下面的注释),它会崩溃,而不仅仅是一个线程,而是整个进程。它不会影响其他进程,因为它们的内存空间是隔离的。 (在Windows 95等旧操作系统中并非如此,其中所有进程共享相同的内存空间。)
在C ++中,堆栈分配的对象在输入块时创建,并在退出块时销毁。虽然堆栈上的实际空间可能分配得不那么精确,但构造和破坏将在这些特定点进行。
x86进程上的堆栈指针可以任意操作。编译器通常只生成向堆栈指针添加空间量的代码,然后为堆栈中的值设置内存,而不是进行一堆推送操作。
进程的堆栈和堆都存在于同一个内存空间中。
有关如何组织内存的概述可能会有所帮助:
答案 1 :(得分:2)
delete
它指向的值,但是否则无法清除该内存。应用程序退出时会自动调用全局变量的析构函数(好吧,可能不会使用SIGTERM)