2017-03-02 21 views
2

我有一个本机C++应用程序,我正在调用.net dll(外部函数),我发现当我打电话给托管时,它分配完整的堆栈分配对于使用/ stack连接器选项指定的线程,但是如果我只进行本机函数调用,它会分配计算所需的堆栈。混合模式下的内存使用过多C++/CLR应用程序

下面是我的观察

设置为80MB /堆栈选项,并通过调用外部管理功能。 enter image description here

将/ stack选项设置为1MB,并调用托管的外部函数。 enter image description here

将/ stack选项设置为80MB,并调用本地内部函数。 enter image description here

当我们调用.Net外部函数时,还有一些额外的线程与GC有关。与我们不调用.Net外部函数的情况相比,我们的应用程序中的线程也使用了更多的堆栈空间。我不确定托管堆栈是否位于本地堆栈之上。有人可以帮助我理解为什么当我们调用.Net外部函数以及混合模式应用程序中的内存管理时,为线程分配了全部堆栈。

回答

2

好的,我终于找到答案。

一旦创建托管线程,CLR就会始终为托管线程提交整个堆栈内存,或者在本地线程变为托管线程时,CLR始终提交。这是为了确保堆栈溢出可以由执行引擎预测处理。

在托管代码中,System.Threading.Thread类的构造函数提供了两个接受maxStackSize参数的重载。由于完整堆栈在创建时为所有托管线程提交,因此maxStackSize参数同时表示备用和提交大小:它们实际上是相同的。

只是为了澄清,有三个步骤,使用堆栈内存:

储备堆栈的过程中 提交页面 使用

在正常的默认行为页面的虚拟地址空间当一个线程启动时,Win32程序只做1个。问题在于动态堆栈增长在高负载下可能会失败 - 您可能会发现当您想添加堆栈帧时,系统没有任何可用的空闲虚拟内存。

通过执行步骤2,CLR确保内存将保留在备用状态,以便第3步永远不会失败。

有关此任何有用的信息仍然赞赏。 谢谢。

相关问题