【问题标题】:Excessive memory usage in Mixed Mode c++/CLR application混合模式 c++/CLR 应用程序中的内存使用过多
【发布时间】:2017-07-22 17:25:57
【问题描述】:

我有一个本地 c++ 应用程序,我从中调用 .net dll(外部函数),我看到当我调用托管时,它分配了为使用 /stack 链接器选项指定的线程分配的完整堆栈,但是如果我只进行本机函数调用,它会分配计算所需的堆栈。

以下是我的观察

将 /stack 选项设置为 80MB,并调用托管外部函数。

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

将 /stack 选项设置为 80MB,并调用本机内部函数。

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

【问题讨论】:

    标签: c++ .net memory memory-management stack-memory


    【解决方案1】:

    好的,我终于找到了答案。

    CLR 总是在创建托管线程后立即为托管线程提交整个堆栈内存,或者在本机线程成为托管线程时延迟提交。这样做是为了确保执行引擎可以预测地处理堆栈溢出。

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

    澄清一下,在栈上使用内存分为三个步骤:

    为进程中的栈预留虚拟地址空间 提交页面 使用页面

    普通 Win32 程序中的默认行为是在线程启动时只执行 1。这样做的问题是动态堆栈增长可能在高负载下失败 - 您可能会发现当您想要添加堆栈帧时,系统没有任何可用的可用虚拟内存。

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

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

    【讨论】:

      猜你喜欢
      • 2010-11-08
      • 2016-01-10
      • 2011-01-19
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多