关于堆和栈内存使用的问题

3
在Windows操作系统中,堆栈内存是线程特定的存储,调用堆栈是一系列方法的逻辑流程。因此,每个线程都有自己的堆栈区域。我想知道堆内存区域如何使用?它是线程特定的吗?进程特定的吗?或者在.NET中,是AppDomain特定的?还是在所有用户应用程序和操作系统之间共享?非常感谢。
3个回答

3
堆是实现动态内存分配的最常见方式。使用堆的典型情况包括在运行时不知道要分配多少内存,或者所需内存太大以至于无法在堆栈中分配。
一个进程可以拥有一个或多个堆。大多数进程都有多个堆。例如,在Windows中,一个进程可以有默认进程堆、CRT堆,应用程序可以调用Windows API来创建自己的堆(使用API HeapCreate)。
当创建一个进程时,操作系统将为其创建一个名为“默认进程堆”的新堆,在大多数情况下实际上很少使用。当我们调用new/delete和malloc/free时,实际上是在使用CRT堆。
Windows使用一些复杂的数据结构和算法来确保堆中的内存分配/释放和管理是有效的。然而,通常的事实是在堆中分配内存比在堆栈中慢得多。
如果想了解更详细的信息,可以阅读Jeffrey Richter的伟大著作《Windows via C/C++》。您也可以在这里快速了解Windows如何在内部管理堆。

1

一个进程内可以运行多个应用程序域,但每个应用程序域都有自己的数据集合和堆。

你确定吗Justin?我已经尝试了一个简单的命令行应用程序,它将另一个DLL加载到一个单独的应用程序域中并执行它,然后定期报告内存使用情况。

单独的DLL中的代码被设计为逐渐消耗内存。

结果是控制台应用程序报告其自己的应用程序域中分配的内存量增加,直到整个应用程序由在单独应用程序域下运行的线程的内存不足异常关闭。

这种行为在运行.NET 2的32位XP SP3机器上观察到,并且表明单独的应用程序域共享同一进程堆。

如果其他人的经验不是这样的,我很想知道如何使我的应用程序免受有毒的DLL的影响。


1
一些背景:通常用于保存在程序执行期间动态分配的内存。相比之下,上的内存通常仅用于单个函数调用的生命周期 - 即当函数返回时,该内存不再使用。
每个进程都有自己的虚拟内存集,因此不同的进程具有自己的私有堆。
进程中的线程共享同一池内存(堆),因此需要注意确保一个线程不会“破坏”另一个线程的内存。
多个应用程序域可以在单个进程中运行,但每个应用程序域都将具有其自己的数据集和堆。

由于实际内存限制对问题不是关键因素,因此我从答案中删除了它们的限制... - Justin Ethier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接