12

我有一个 C# 应用程序,它必须与 32 位库链接,并且还需要使用可能的最大内存量(成像应用程序);我们在 XP64 桌面上运行应用程序,因此我们使用 WOW64,针对 x86 的 Visual Studio 中的构建(并进行editbin /largeaddressaware后期构建)。我们遇到了几个问题:

  • 在 Visual Studio 内置调试​​器中,我们只能使用 2gb 内存(大约 1.5gb 到应用程序,加上开销)

  • 从命令行运行,应用程序可以看到 3gb 的内存,但微软文档似乎说我们应该看到 4gb。

谁能告诉我如何让 WOW64 C# 应用程序查看平台应该能够提供的完整 4gb?

另外,谁能告诉我如何让 Visual Studio(VS 2008,也称为 VS90)调试器遵守该/largeaddressaware位并停止将应用程序内存限制为 2gb?

我在 VS80 和 VS90 中看到了相同的行为;.NET Framework 3.5、3.0 和 2.0 之间也没有区别。这是一个说明问题的简单 C# 程序;为 x86 构建editbin /largeaddressaware,然后在内置调试器中运行与从命令行运行以查看 C# 可用内存的差异。

namespace MemoryAllocTest
{
class Program
{
    static void Main(string[] args)
    {
        const int allocSize = 1024 * 1024;
        List<byte[]> myMem = new List<byte[]>();
        UInt64 totalAlloc = 0;

        while (true)
        {
            myMem.Add(new byte[allocSize]);
            totalAlloc += allocSize;
            Console.WriteLine("{0} allocs: {1}MB total", 
             myMem.Count, totalAlloc / (1024 * 1024));
        }
    }
}
}
4

6 回答 6

5

谁能告诉我如何让 Visual Studio(VS 2008,也称为 VS90)调试器遵守 /largeaddressaware 位并停止将应用程序内存限制为 2gb?

这需要两个步骤——都在项目属性中:

  • 在构建事件选项卡上,设置构建后步骤以运行 editbin /largeaware $(TargetPath)
  • 在调试选项卡上,取消选中启用 Visual Studio 托管进程

通过这两个步骤,您的示例程序运行到 3045MB

于 2009-04-29T22:44:45.683 回答
3

感谢大家的回应; 这个网站真的很震撼!

似乎我们确实在 WOW64 中达到了 4gb 用户空间,但在我看来(有根据的猜测)垃圾收集器开销(或者可能是安全裕度)随着托管代码分配的内存的增长而变得相当大。在 WOW64(命令行,使用 LARGEADDRESSAWARE)上运行我的测试应用程序,我得到了 3175MB 的总分配;在具有 4GT 参数集的 WIN32 XP 机器上运行,我得到了 2857MB 的总分配:因此,额外的用户模式内存的完整演出在 C# 应用程序级别仅增加了约 318MB!

(我已经修改了我的测试程序,以便在分配失败时将分配单元大小减半,并且还添加了策略性地强制垃圾收集的调用,以稍微超出“正常”应用程序可能能够抓取的限制 - - 如果您希望我发布修改后的代码,请在此处添加注释。)

无论如何,再次感谢大家;看起来系统工作正常,但托管环境从额外的内存中得到的改进比预期的要小。

于 2009-04-30T17:23:06.667 回答
2

我从帖子中构建了您的简单示例应用程序,将其崩溃并将 WinDbg 附加到它。

!address -summary 将显示进程的有效用户模式地址空间。

0:003> !address -summary
 TEB fffdd000 in range fffdb000 fffde000
 TEB fffda000 in range fffd8000 fffdb000
 TEB fffd7000 in range fffd5000 fffd8000
 TEB fffaf000 in range fffad000 fffb0000
 ProcessParametrs 004c2b40 in range 004c0000 00535000
 Environment 004c1978 in range 004c0000 00535000

-------------------- Usage SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots) Pct(Busy)   Usage
   e7d2e000 ( 3798200) : 90.56%    98.77%    : RegionUsageIsVAD
   1547b000 (  348652) : 08.31%    00.00%    : RegionUsageFree
    2887000 (   41500) : 00.99%    01.08%    : RegionUsageImage
     3ff000 (    4092) : 00.10%    00.11%    : RegionUsageStack
          0 (       0) : 00.00%    00.00%    : RegionUsageTeb
     1c0000 (    1792) : 00.04%    00.05%    : RegionUsageHeap
          0 (       0) : 00.00%    00.00%    : RegionUsagePageHeap
       1000 (       4) : 00.00%    00.00%    : RegionUsagePeb
          0 (       0) : 00.00%    00.00%    : RegionUsageProcessParametrs
          0 (       0) : 00.00%    00.00%    : RegionUsageEnvironmentBlock
       **Tot: ffff0000 (4194240 KB)** Busy: eab75000 (3845588 KB)

-------------------- Type SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots)  Usage
   1547b000 (  348652) : 08.31%   : <free>
    2aa3000 (   43660) : 01.04%   : MEM_IMAGE
    1f6a000 (   32168) : 00.77%   : MEM_MAPPED
   e6168000 ( 3769760) : 89.88%   : MEM_PRIVATE

-------------------- State SUMMARY --------------------------
    TotSize (      KB)   Pct(Tots)  Usage
   db838000 ( 3596512) : 85.75%   : MEM_COMMIT
   1547b000 (  348652) : 08.31%   : MEM_FREE
    f33d000 (  249076) : 05.94%   : MEM_RESERVE

Largest free region: Base fbfc0000 - Size 03fed000 (65460 KB)

基于 Tot: ffff0000 (4194240 KB) 我们确实有 4GB 的有效用户模式空间。

此外,我们最大的空闲块是 65,460KB,这确实意味着我们应该能够分配更多的内存。

于 2009-04-29T21:50:53.833 回答
2

来自微软

除非在 Boot.ini 文件中使用 /3GB 开关,否则进程和应用程序的虚拟地址空间仍被限制为 2 GB。当系统中的物理 RAM 超过 16 GB 并使用 /3GB 开关时,操作系统将忽略额外的 RAM,直到 /3GB 开关被移除。这是因为支持更多页表条目所需的内核大小增加了。假设管理员宁愿不默默地自动丢失 /3GB 功能;因此,这需要管理员明确更改此设置。/3GB 开关将 3 GB 的虚拟地址空间分配给使用 IMAGE_FILE_LARGE_ADDRESS_AWARE在进程头中。此开关允许应用程序寻址超过 2 GB 的 1 GB 额外虚拟地址空间。

于 2009-04-29T19:42:24.733 回答
2

您使用的是什么确切版本的 .NET?这个 Connect 报告是关于相同的问题(据我所知),在 .NET 2.0 上可以看到,但在 .NET 2.0SP1 中已修复。

如果您的 x64 机器没有 2.0SP1(或更高版本),那么值得一试...

于 2009-04-29T19:43:12.720 回答
1

你能在暗示你可以看到所有 4 GB 的地方发帖吗?哦,也许在这里:此链接上的有趣信息

可寻址内存的差异

大多数开发人员首先注意到的是 64 位处理器在可寻址的物理和虚拟内存量方面提供了巨大的飞跃。

* 32-bit applications on 32-bit platforms can address up to 2 GB
* 32-bit applications built with the /LARGEADDRESSAWARE:YES linker flag

在具有特殊 /3gb 引导选项的 32 位 Windows XP 或 Windows Server 2003 上,最多可以寻址 3 GB。这将内核限制为仅 1 GB,这可能会导致某些驱动程序和/或服务失败。

* 32-bit applications built with the /LARGEADDRESSAWARE:YES linker flag

在 32 位版本的 Windows Vista 和 32 位版本的 Windows Server 代码名称“Longhorn”操作系统上,最多可以寻址由引导配置数据 (BCD) 元素增加用户Va 指定的数量的内存。increaseUserVa 的值可以从默认值 2048 到 3072(与 Windows XP 上的 /3gb 引导选项配置的内存量相匹配)。剩余的 4 GB 分配给内核,可能导致驱动程序和服务配置失败。

有关 BCD 的详细信息,请参阅 MSDN 上的引导配置数据。

* 32-bit applications on 64-bit platforms can address up to 2 GB, or up

使用 /LARGEADDRESSAWARE:YES 链接器标志到 4 GB。* 64 位应用程序使用 43 位寻址,为应用程序提供 8 TB 的虚拟地址,为内核保留 8 TB。

所以是的,看来您应该(在 XP64 目标上)能够看到 4 GB。

于 2009-04-29T19:43:38.333 回答