为32位.net程序开启内存地址拓展突破2G内存限制

32位的.net程序在默认情况内存占用限制为2G,而在实际使用过程中,占用超过1.3G左右(个人观察)就容易出现内存不足的报错甚至直接崩溃。而VS系列IDE附带的命令行工具其实提供了内存地址拓展功能,可以突破该限制使用4G左右的内存。

命令行工具位于VS安装目录下的一个文件夹,可以通过打开Windows的系统变量窗口来确定该文件夹的系统级环境变量(以“%”开头和结尾,可以在路径中作为变量使用),比如下图为Win11 + VS2019的组合的环境变量:“%VS160COMCOMNTOOLS%”。

Win11 + VS2019 的系统环境变量

具体工具的调用批处理文件名为“VsDevCmd.bat”,请注意,在VS2015及之前的版本中,该文件名为“VsVars32.bat”。

为了避免每次工程生成后需要手动调用,可以在项目的属性中,生成事件选项卡的“生成后事件命令行”中添加如下命令(路径请自行修改):

call “%VS160COMCOMNTOOLS%\VsDevCmd.bat” && editbin /largeaddressaware $(TargetPath)

其中“$(TargetPath)”会自动指代生成的32位程序。

配置完毕后,每次生成工程成功后,会自动调用命令行工具给程序拓展内存地址,在输出栏中,如果出现一下信息,可以视为调用成功:

4>
4> ** Visual Studio 2019 Developer Command Prompt v16.11.5
4> ** Copyright (c) 2021 Microsoft Corporation
4>
4> Microsoft (R) COFF/PE Editor Version 14.29.30136.0
4> Copyright (C) Microsoft Corporation. All rights reserved.
4>
========== 全部重新生成: 成功 4 个,失败 0 个,跳过 0 个 ==========

修改成功与否,可在程序启动的部分中加入以下代码,查看调试界面的内存占用情况。

try
{
int count = 100000000;
List lst = new List(count);
for (int i = 0; i < count; i++)
lst.Add(new int[1000000]);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}

下面两张图依次为未启用和启用后的内存占用情况,若启用后弹窗时占用能够达到4G左右,则说明修改生效。

未启用内存地址拓展的内存占用
启用内存地址拓展后的内存占用

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注